如何将我的服务开放给用户:构建 API 接口和用户认证的实践指南(上)|青训营

240 阅读4分钟

依赖准备

使用gin进行API接口构建,首先需要先下载相关库,进行导入

go get "github.com/gin-gonic/gin"

这样就可以下载我们得到gin相关库。这里我们需要了解ResultAPl规范。我们应该可以发现,我们开发的一个个Web应用服务或者程序,其实就是对服务器的资源的CRUD(创建、检索、更新和删除),所以 RESTful API 的规范建议我们使用特定的HTTP方法来对服务器上的资源进行操作。

在 RESTful API 中,使用的主要是以下五种HTTP方法:

  1. GET,表示读取服务器上的资源
  2. POST,表示在服务器上创建资源
  3. PUT,表示更新或者替换服务器上的资源
  4. DELETE,表示删除服务器上的资源
  5. PATCH,表示更新/修改资源的一部分

一个简单的demo

这一个demo不涉及于数据库。这里我们就做一个请求,看看是否能获得相关数据。

    engine := gin.Default()
    group := engine.Group("/api")
    group.GET("/hello", func(context *gin.Context) {
        context.json(http.StatusOK,"hello world")
    })
    engine.run(":8080")

简单解释上述代码首先选择使用本机,然后创建组(可以把相同能力代码汇总),GET函数的两个参数是第一个是路径,第二个是处理逻辑。我们这里context.json(返回码,相应数据)。run就是选择相关端口。这里访问地址https://127.0.0.1:8080/api/hello就可以看到网页给我们返回hello world

gin和gorm融合使用

接下来演示操作就是通过连接数据库,然后通过客户端请求进行访问。定义结构体


type customer struct {
    No   int8   `json:"No" gorm:"primaryKey" form:"No""`
    name string `json:"Name" form:"name"`
}


func (customer) TableName() string {
    return "customers"
}


func newTable() {
    db.AutoMigrate(customer{})
}


//连接数据库
...

var db *gorm.DB

func main(){
// 创建 gin 路由
    r := gin.Default()

    // 添加路由处理程序
    r.GET("/customers/:id", GetCustomer())
    r.POST("/customers", CreateCustomer())
    r.PUT("/customers/:id", UpdateCustomer())
    r.DELETE("/customers/:id", DeleteCustomer())
    }

创建数据

然后我们首先编写CreateCutomer(),创建相关顾客信息,并需要写入数据库。

func CreateCustomer() gin.HandlerFunc {
	return func(c *gin.Context) {
		var customer Customer
		if err := c.ShouldBindJSON(&customer); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid customer data"})
			return
		}

		result := db.Create(&customer)
		if result.RowsAffected == 0 {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create customer"})
			return
		}

		c.JSON(http.StatusOK, customer)
	}
}

首先声明customer结构体,ShouldBindJSON 是 Gin 框架的一个方法,用于将请求的 JSON 数据绑定到指定的结构体对象中。然后检查没有错误,就会在数据库中插入这一条数据。如果没没有影响的话,会返回响应出错。

查找数据


func GetCustomer() gin.HandlerFunc {
	return func(c *gin.Context) {
		id := c.Param("id")

		var customer Customer
		err := db.First(&customer, id).Error
		if err != nil {
			c.JSON(http.StatusNotFound, gin.H{"error": "Customer not found"})
			return
		}

		c.JSON(http.StatusOK, customer)
	}
}

这里id := c.Param("id")定义了一个 GET 路由 /customers/:id,并通过 c.Param("id") 来获取路由参数 id 的值,并将其响应为 JSON 数据。查找第一个顾客数据,返回相关json数据。

更改数据

func UpdateCustomer() gin.HandlerFunc {
	return func(c *gin.Context) {
		id := c.Param("id")

		var customer Customer
		err := db.First(&customer, id).Error
		if err != nil {
			c.JSON(http.StatusNotFound, gin.H{"error": "Customer not found"})
			return
		}

		if err := c.ShouldBindJSON(&customer); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid customer data"})
			return
		}

		db.Save(&customer)

		c.JSON(http.StatusOK, customer)
	}
}

首先,定义了一个名为 UpdateCustomer 的函数,它返回一个 gin.HandlerFunc,并通过匿名函数实现了路由处理逻辑。id := c.Param("id") 语句从请求的路由参数中获取具体的顾客ID,并将其存储在 id 变量中。接下来,创建了一个名为 customer 的 Customer 结构体变量,并使用 db.First(&customer, id) 查询数据库中对应ID的顾客信息。如果查询结果出现错误(例如,找不到该顾客),则返回状态码为 404 的 JSON 响应,表示顾客未找到。接下来,创建了一个名为 customer 的 Customer 结构体变量,并使用 db.First(&customer, id) 查询数据库中对应ID的顾客信息。如果查询结果出现错误(例如,找不到该顾客),则返回状态码为 404 的 JSON 响应,表示顾客未找到。最后,在经过上述两个检查后,调用 db.Save(&customer) 方法将更新后的顾客信息保存回数据库中。然后,将顾客信息作为 JSON 响应返回,表示成功更新了顾客信息。

删除数据

// DeleteCustomer 删除顾客
func DeleteCustomer() gin.HandlerFunc {
	return func(c *gin.Context) {
		id := c.Param("id")

		var customer Customer
		err := db.First(&customer, id).Error
		if err != nil {
			c.JSON(http.StatusNotFound, gin.H{"error": "Customer not found"})
			return
		}

		db.Delete(&customer)

		c.JSON(http.StatusOK, gin.H{"message": "Customer deleted successfully"})
	}

首先,定义了一个名为 DeleteCustomer 的函数,它返回一个 gin.HandlerFunc,并通过匿名函数实现了路由处理逻辑。id := c.Param("id") 语句从请求的路由参数中获取具体的顾客 ID,并将其存储在 id 变量中。接下来,创建了一个名为 customer 的 Customer 结构体变量,并使用 db.First(&customer, id) 查询数据库中对应ID的顾客信息。如果查询结果出现错误(例如,找不到该顾客),则返回状态码为 404 的 JSON 响应,表示顾客未找到。然后,调用 db.Delete(&customer) 方法将查询到的顾客从数据库中删除。最后,返回状态码为 200 的 JSON 响应,表示成功删除了顾客。

上述代码,我们可以使用apifox还有直接通过网址进行访问,测试增删改查是否成功。gin的学习成本很低,学习使用起来非常方便。