go
复制代码
package main
import (
"fmt"
"log"
"net/http"
"github.com/gin-gonic/gin"
)
// 定义结构体
type Book struct {
Name string `json:"name"`
Author string `json:"author"`
}
func main() {
// 创建默认的gin路由引擎
server := gin.Default()
// 创建业务路由 并返回数据
server.GET("/api/hello", func(c *gin.Context) {
c.JSON(200, gin.H{
"code": 0,
"message": "Hello World",
"data": nil,
})
})
// gin框架读取参数
/*
1 读取url路径参数
/ api/books/:name
server.GET("/api/books/:name/:year/:month", func(c *gin.Context) {})
请求
curl --location --request GET 'http://127.0.0.1:18080/api/books/testBook'
返回
{
"code": 0,
"data": null,
"message": "testBook"
}
*/
// 接口示例
server.GET("/api/books/:name", func(c *gin.Context) {
// c.Param 读取参数
name := c.Param("name")
// 返回JSON数据
c.JSON(http.StatusOK, gin.H{
"code": 0,
"message": name,
"data": nil,
})
})
/*
2 读取url 查询参数
/api/books?pageSize=10&pageNum=1
请求
curl --location --request GET 'http://127.0.0.1:18080/api/books?pageSize=1000&pageNum=10'
返回
{
"code": 0,
"data": null,
"message": "pageSize=1000&pageNum=10"
}
*/
// 接口示例
server.GET("/api/books", func(c *gin.Context) {
ps := c.Query("pageSize")
pn := c.Query("pageNum")
returnData := fmt.Sprintf("pageSize=%s&pageNum=%s", ps, pn)
c.JSON(http.StatusOK, gin.H{
"code": 0,
"message": returnData,
"data": nil,
})
})
/*
3 读取header参数
常用于接口认证 Authorization Bearer xxxxxxx
请求
curl --location --request GET 'http://127.0.0.1:18080/api/bookAuth' --header 'Authorization: Bearer test_token'
返回
{
"code": 0,
"data": null,
"message": "Bearer test_token"
}
*/
// 接口示例
server.GET("/api/bookAuth", func(c *gin.Context) {
auth := c.GetHeader("Authorization")
c.JSON(http.StatusOK, gin.H{
"code": 0,
"message": auth,
"data": nil,
})
})
/*
4 body中读取参数 推荐ShouldBindJson
一般用于提交数据 POST请求 或者 PUT 等
{"name":"初始Go语言","author":"XiaoLx005"}
JSON -- struct
// 请求
curl --location --request POST 'http://127.0.0.1:18080/api/books' --header 'Content-Type: application/json' \
--data-raw '{
"name":"初始Go语言",
"author":123
}'
// 返回
{
"code": 1,
"data": null,
"message": "json: cannot unmarshal number into Go struct field Book.author of type string"
}
ShouldBindJSON和BindJSON的区别以及使用场景
ShouldBindJSON:
绑定 JSON 数据时,如果出现错误(例如 JSON 数据格式不符合预期、类型不匹配等),
它不会直接返回 HTTP 错误响应。而是返回一个错误值,由开发者决定如何处理这个错误。例如:
if err := c.ShouldBindJSON(&user); err!= nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
适用于需要对错误进行详细记录、自定义错误处理逻辑(比如根据不同的错误类型返回不同的状态码或消息)的情况。
例如,在一个复杂的微服务架构中,可能需要将错误信息发送到专门的错误收集服务进行分析,此时ShouldBindJSON就很有用。
BindJSON:
绑定 JSON 数据出现错误,它会自动返回一个状态码为 400(Bad Request)的响应给客户端,
并且在响应体中包含了错误信息。例如:
if err!= nil {
// 这里不需要手动返回错误响应,因为BindJSON已经自动返回了
return
}
适用于简单的 API 场景,对于错误处理要求不高,只需要快速返回一个基本的错误提示给客户端的情况。
例如,一个小型的内部工具的 API,主要关注功能实现,对于错误处理只要符合常见的 HTTP 规范(返回 400 错误)就足够了。
*/
// 接口示例 结构体定义在函数外
server.POST("/api/books", func(c *gin.Context) {
// 定义变量 为Book struct
//var book Book
book := new(Book)
// c.ShouldBindJSON 将上下文接收的数据 绑定 结构体数据
err := c.ShouldBindJSON(&book)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"code": 1,
"message": err.Error(),
"data": nil,
})
} else {
c.JSON(http.StatusOK, gin.H{
"code": 0,
"message": "success",
"data": nil,
})
}
})
// 启动服务 指定端口
err := server.Run(":18080")
// 错误处理
if err != nil {
panic(err)
} else {
log.Println("Server started")
}
}