跳到主要内容

配置API

前言

在这篇文章中,我们将探讨 Gin 中的核心部分:路由系统。Gin 提供了简洁的 API 路由定义方式,方便开发者快速构建 RESTful API。

主要内容:

  • 如何创建基础API
  • 如何使用路由组组织API
  • 如何为静态文件提供Web服务

创建基础API

在 Gin 中创建一个简单的 API 非常方便。通常,我们可以使用路由方法(如 GETPOSTPUTDELETE)来定义 API 路径。在第一节已经提供了一个HelloWorld的示例代码,这里再解释下。在main()函数中,首先初始化一个Gin路由器实例。gin.Default()会返回一个默认的Gin路由器,包括日志记录中间件和恢复中间件。router.GET("/", func(xxx))定义了一个路由,处理 HTTP GET 请求,路由路径是 /。当用户访问根路径时,会执行对应的执行器函数,这里的执行器函数是一个匿名函数,参数统一为*gin.Contextc.JSON()将会返回一个JSON格式的响应。gin.H 是 Gin 提供的一个便捷类型,等价于 map[string]interface{}router.Run("127.0.0.1:8000"):启动 HTTP 服务器并监听 127.0.0.1:8000 这个地址和端口。也就是说,服务器会在本地的 8000 端口上等待并处理请求。

package main

import (
"net/http"

"github.com/gin-gonic/gin"
)

func main() {
router := gin.Default()
router.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "hello world",
})
})
router.Run("127.0.0.1:8000")
}

上面用的执行器函数是一个匿名函数,也可以声明一个函数,然后绑定到路由。

package main

import (
"net/http"

"github.com/gin-gonic/gin"
)

func IndexHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "hello world",
})
}

func main() {
router := gin.Default()
router.GET("/", IndexHandler) // 将IndexHandler绑定到 "/" 路径
router.Run("127.0.0.1:8000")
}

路由组

Gin提供路由组(Route Group)的机制,用于组织和管理有相关性的路由。在实际应用中,特别是在大型应用中,路由组能够帮助开发者更清晰地组织和分配路由。如果用过python的flask,这就相当于flask的蓝图机制。

如下代码中定义了两个路由组,一个v1,另一个v2v1路由组下面的API都会以/v1开头。

package main

import (
"net/http"
"github.com/gin-gonic/gin"
)

func Hello(c *gin.Context){
name := c.Param("name")

c.JSON(http.StatusOK, gin.H{
"hello": name,
})
}

func main() {
r := gin.Default()
// 方式1, 用一对 {} 表示这些API属于v1用户组
v1 := r.Group("/v1")
{
v1.GET("/user/:name", Hello)
}

// 方式2, 也可以不用 {}
v2 := r.Group("/v2")
v2.GET("/user/:name", Hello)

r.Run("127.0.0.1:8000")
}

在命令行使用curl命令测试,也可以在浏览器直接访问url。

$ curl http://127.0.0.1:8000/v1/user/zhangsan
{"hello":"zhangsan"}

$ curl http://127.0.0.1:8000/v2/user/lisi
{"hello":"lisi"}

在某些项目中还可以看到这样的API组织方法,各个路由组在不同的函数中,这样NewRoute()函数看起来会更加简洁清晰。

package route

import (
"short-url-go/handlers"
"short-url-go/middlewares"

"github.com/gin-gonic/gin"
)

func NewRoute() *gin.Engine {
r := gin.Default()
r.GET("/health", handlers.Health)
loadUser(r)
loadShortUrl(r)
return r
}

func loadUser(r *gin.Engine) {
userHandler := handlers.NewUserHandler()

routeGroup := r.Group("/user")
routeGroup.POST("/register", userHandler.RegisterUser)
routeGroup.POST("/login", userHandler.LoginUser)
routeGroup.POST("/logout", userHandler.Logout)

}

func loadShortUrl(r *gin.Engine) {
svc := handlers.NewShorturlHandler()

group := r.Group("/t")
group.GET("/:shorturl", svc.GetShortUrl)
// 为该API设置中间件
group.POST("/add", middlewares.JWTAuthMiddleware(), svc.CreateShortUrl)
}

静态文件服务

在 Web 开发中,静态文件(如图片、CSS、JavaScript)通常需要公开访问。Gin 提供了简单的方法来配置静态文件目录,允许应用为静态文件设置专门的访问路径。

package main

import (
"net/http"

"github.com/gin-gonic/gin"
)

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

// 以 /assets 开头的路径时,Gin 将会从本地的 ./assets 目录中提供文件
router.Static("/assets", "./assets")

// StaticFS作用类似Static, 但是更加灵活, 可以使用自定义的文件系统,包括本地目录或其他存储形式(比如OSS)
router.StaticFS("/more_static", http.Dir("my_file_system"))

// 这一行配置了一个单独的静态文件映射。它告诉 Gin,当用户请求 /favicon.ico 路径时,直接返回 ./resources/favicon.ico 文件。
router.StaticFile("/favicon.ico", "./resources/favicon.ico")

router.Run(":8080")
}