Gin框架入门系列【3】数据响应

783 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

数据响应

在之前的内容中了解了Gin框架有关于路由方面的知识,在实际情况中,当前端请求我们后端接口之后,我们需要根据前端的要求返回对应的http状态响应码和数据,在Gin框架中可以返回的数据有很多格式,例如最常用的JSON格式,除此之外还有XML、String以及YAML格式的数据。

响应码

在之前的代码中,我们返回时使用到了c.JSON的方法,代码如下所示:

v1.GET("/get_user", func(c *gin.Context) {
  c.JSON(http.StatusOK, gin.H{
    "message": "ok",
  })
})

在上面的代码中,c.JSON方法传递的有两个参数,一个是int类型的状态响应码,另外就是需要返回的具体数据,状态响应码包括200、404、500等(具体类型自行查阅),在返回时我们直接填入int类型的数字也可以使用http包中已经规定好的状态码常量。

http包常量如下:

const (
  StatusContinue           = 100 // RFC 9110, 15.2.1
  StatusSwitchingProtocols = 101 // RFC 9110, 15.2.2
  StatusProcessing         = 102 // RFC 2518, 10.1
  StatusEarlyHints         = 103 // RFC 8297

  StatusOK                   = 200 // RFC 9110, 15.3.1
  StatusCreated              = 201 // RFC 9110, 15.3.2
  StatusAccepted             = 202 // RFC 9110, 15.3.3
  StatusNonAuthoritativeInfo = 203 // RFC 9110, 15.3.4
  StatusNoContent            = 204 // RFC 9110, 15.3.5
  StatusResetContent         = 205 // RFC 9110, 15.3.6
  StatusPartialContent       = 206 // RFC 9110, 15.3.7
  StatusMultiStatus          = 207 // RFC 4918, 11.1
  StatusAlreadyReported      = 208 // RFC 5842, 7.1
  StatusIMUsed               = 226 // RFC 3229, 10.4.1

  StatusMultipleChoices   = 300 // RFC 9110, 15.4.1
  StatusMovedPermanently  = 301 // RFC 9110, 15.4.2
  StatusFound             = 302 // RFC 9110, 15.4.3
  StatusSeeOther          = 303 // RFC 9110, 15.4.4
  StatusNotModified       = 304 // RFC 9110, 15.4.5
  StatusUseProxy          = 305 // RFC 9110, 15.4.6
  _                       = 306 // RFC 9110, 15.4.7 (Unused)
  StatusTemporaryRedirect = 307 // RFC 9110, 15.4.8
  StatusPermanentRedirect = 308 // RFC 9110, 15.4.9

  StatusBadRequest                   = 400 // RFC 9110, 15.5.1
  StatusUnauthorized                 = 401 // RFC 9110, 15.5.2
  StatusPaymentRequired              = 402 // RFC 9110, 15.5.3
  StatusForbidden                    = 403 // RFC 9110, 15.5.4
  StatusNotFound                     = 404 // RFC 9110, 15.5.5
  StatusMethodNotAllowed             = 405 // RFC 9110, 15.5.6
  StatusNotAcceptable                = 406 // RFC 9110, 15.5.7
  StatusProxyAuthRequired            = 407 // RFC 9110, 15.5.8
  StatusRequestTimeout               = 408 // RFC 9110, 15.5.9
  StatusConflict                     = 409 // RFC 9110, 15.5.10
  StatusGone                         = 410 // RFC 9110, 15.5.11
  StatusLengthRequired               = 411 // RFC 9110, 15.5.12
  StatusPreconditionFailed           = 412 // RFC 9110, 15.5.13
  StatusRequestEntityTooLarge        = 413 // RFC 9110, 15.5.14
  StatusRequestURITooLong            = 414 // RFC 9110, 15.5.15
  StatusUnsupportedMediaType         = 415 // RFC 9110, 15.5.16
  StatusRequestedRangeNotSatisfiable = 416 // RFC 9110, 15.5.17
  StatusExpectationFailed            = 417 // RFC 9110, 15.5.18
  StatusTeapot                       = 418 // RFC 9110, 15.5.19 (Unused)
  StatusMisdirectedRequest           = 421 // RFC 9110, 15.5.20
  StatusUnprocessableEntity          = 422 // RFC 9110, 15.5.21
  StatusLocked                       = 423 // RFC 4918, 11.3
  StatusFailedDependency             = 424 // RFC 4918, 11.4
  StatusTooEarly                     = 425 // RFC 8470, 5.2.
  StatusUpgradeRequired              = 426 // RFC 9110, 15.5.22
  StatusPreconditionRequired         = 428 // RFC 6585, 3
  StatusTooManyRequests              = 429 // RFC 6585, 4
  StatusRequestHeaderFieldsTooLarge  = 431 // RFC 6585, 5
  StatusUnavailableForLegalReasons   = 451 // RFC 7725, 3

  StatusInternalServerError           = 500 // RFC 9110, 15.6.1
  StatusNotImplemented                = 501 // RFC 9110, 15.6.2
  StatusBadGateway                    = 502 // RFC 9110, 15.6.3
  StatusServiceUnavailable            = 503 // RFC 9110, 15.6.4
  StatusGatewayTimeout                = 504 // RFC 9110, 15.6.5
  StatusHTTPVersionNotSupported       = 505 // RFC 9110, 15.6.6
  StatusVariantAlsoNegotiates         = 506 // RFC 2295, 8.1
  StatusInsufficientStorage           = 507 // RFC 4918, 11.5
  StatusLoopDetected                  = 508 // RFC 5842, 7.2
  StatusNotExtended                   = 510 // RFC 2774, 7
  StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6
)

String

String格式是接口响应中最基本的一种返回格式,使用String也比较简单,直接调用String方法即可,String方法签名如下:

func (c *Context) String(code int, format string, values ...any) {}

code:状态响应码

format:格式化字符串

values:格式化值

String方法中可以使用格式化字符串,也就表示可以在字符串中使用%d,%s等。

示例代码:

func main() {
  g := gin.Default()

  g.GET("/test", func(c *gin.Context) {
    c.String(http.StatusOK, "hello, %s, %d", "lee", 20)
  })

  err := g.Run(":8888")
  if err != nil {
    return
  }
}

响应结果:

JSON

JSON格式就是之前代码示例中使用到的格式,也是开发中使用到的最多的一种格式,JSON方法签名如下:

func (c *Context) JSON(code int, obj any) {}

code:状态响应码

obj:具体返回数据

obj是具体返回的内容,可以接收任何类型的数据,但是我们通常都是使用gin.H传入一个map类型的数据。

示例代码:

func main() {
  g := gin.Default()

  g.GET("/test", func(c *gin.Context) {
    c.JSON(http.StatusOK, gin.H{
      "message": "ok",
    })
  })

  err := g.Run(":8888")
  if err != nil {
    return
  }
}

除了使用gin.H方法传入map类型之外,我们还可以直接使用Go语言中的结构体当做返回数据,这也是实际开发中使用比较多的方法。

代码示例:

type Person struct {
  Name string
  Age  int
}

func main() {
  g := gin.Default()

  g.GET("/test", func(c *gin.Context) {
    person := Person{
      Name: "lee",
      Age:  23,
    }
    c.JSON(http.StatusOK, person)
  })

  err := g.Run(":8888")
  if err != nil {
    return
  }
}

响应结果:

XML

XML也是开发中使用到比较多的一种返回格式,XML方法签名如下:

func (c *Context) XML(code int, obj any) {}

code:状态响应码

obj:具体返回数据

和JSON返回格式一样,obj也是可以接收任意类型的数据,同样的也可以使用gin.H传入一个map类型的数据。

代码示例:

func main() {
  g := gin.Default()

  g.GET("/test", func(c *gin.Context) {
    c.XML(http.StatusOK, gin.H{
      "message": "ok",
    })
  })

  err := g.Run(":8888")
  if err != nil {
    return
  }
}

响应结果:

YAML

在Gin框架中还可以返回YAML格式的数据,YAML是一种常用于配置文件的格式,YAML的方法签名如下:

func (c *Context) YAML(code int, obj any) {}

code:状态响应码

obj:具体返回数据

YAML的使用方法和JSON以及XML都是一样,只是最后再返回到客户端时会自动将格式转换为YAML。

代码示例:

func main() {
  g := gin.Default()

  g.GET("/test", func(c *gin.Context) {
    c.YAML(http.StatusOK, gin.H{
      "message": "OK",
    })
  })

  err := g.Run(":8888")
  if err != nil {
    return
  }
}

响应结果: