展示 Gin 框架的基本使用,包括路由、中间件、参数获取、用户认证、JSON 响应等基本功能。
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
var db = make(map[string]string)
func setupRouter() *gin.Engine {
// Disable Console Color
// gin.DisableConsoleColor()
r := gin.Default()
// Ping test
r.GET("/ping", func(c *gin.Context) {
c.String(http.StatusOK, "pong")
})
// Get user value
r.GET("/user/:name", func(c *gin.Context) {
user := c.Params.ByName("name")
value, ok := db[user]
if ok {
c.JSON(http.StatusOK, gin.H{"user": user, "value": value})
} else {
c.JSON(http.StatusOK, gin.H{"user": user, "status": "no value"})
}
})
// Authorized group (uses gin.BasicAuth() middleware)
// Same than:
// authorized := r.Group("/")
// authorized.Use(gin.BasicAuth(gin.Credentials{
// "foo": "bar",
// "manu": "123",
// }))
authorized := r.Group("/", gin.BasicAuth(gin.Accounts{
"foo": "bar", // user:foo password:bar
"manu": "123", // user:manu password:123
}))
/* example curl for /admin with basicauth header
Zm9vOmJhcg== is base64("foo:bar")
curl -X POST \
http://localhost:8080/admin \
-H 'authorization: Basic Zm9vOmJhcg==' \
-H 'content-type: application/json' \
-d '{"value":"bar"}'
*/
authorized.POST("admin", func(c *gin.Context) {
user := c.MustGet(gin.AuthUserKey).(string)
// Parse JSON
var json struct {
Value string `json:"value" binding:"required"`
}
if c.Bind(&json) == nil {
db[user] = json.Value
c.JSON(http.StatusOK, gin.H{"status": "ok"})
}
})
return r
}
func main() {
r := setupRouter()
// Listen and Server in 0.0.0.0:8080
r.Run(":8080")
}
1
var db = make(map[string]string)
:创建了一个全局的字符串到字符串的映射 db
,用于模拟一个简单的数据库,存储用户和对应的值。
2
r := gin.Default()
r := gin.Default()
:gin.Default()
是 Gin 框架提供的一个函数,它返回一个默认的 *gin.Engine
实例。gin.Engine
可以理解为是 Gin 框架的核心引擎,负责管理路由、中间件等。r
在这里就代表这个引擎实例,你可以把它类比成一个类的实例,但在 Go 语言中没有类的概念,更准确地说它是一个结构体的实例。这个实例提供了很多方法来定义路由和处理请求。
r.GET("/ping", func(c *gin.Context) {
c.String(http.StatusOK, "pong")
})
r.GET
:这是 gin.Engine
实例 r
的一个方法,用于注册一个 HTTP GET 请求的路由。第一个参数是路由的路径 /ping
,第二个参数是一个匿名函数,用于处理该路由的请求。
c *gin.Context
:c
是 *gin.Context
类型的指针,它是 Gin 框架中非常重要的一个结构体,用于处理 HTTP 请求和响应。每个请求都会有一个对应的 Context
实例。
c.String
:这是 gin.Context
的一个方法,用于返回一个纯文本的响应。第一个参数是 HTTP 状态码 http.StatusOK
表示 200 状态,第二个参数是响应的文本内容 "pong"
。
3
r.GET("/user/:name")
:注册一个带有参数的 GET 路由,:name
是一个动态参数,表示可以匹配任意的字符串。
c.Params.ByName("name")
:c.Params
是 gin.Context
的一个字段,用于获取路由中的参数。ByName("name")
方法用于获取名为 name
的参数值。
c.JSON
:gin.Context
的一个方法,用于返回一个 JSON 格式的响应。第一个参数是 HTTP 状态码,第二个参数是一个 gin.H
类型的映射,gin.H
是 map[string]interface{}
的别名,用于存储 JSON 数据。
4
authorized := r.Group("/", gin.BasicAuth(gin.Accounts{
"foo": "bar", // user:foo password:bar
"manu": "123", // user:manu password:123
}))
r.Group
:gin.Engine
实例 r
的一个方法,用于创建一个路由组。路由组可以共享一些中间件和前缀。第一个参数是路由组的前缀,这里是 /
表示根路径。第二个参数是一个中间件函数,这里使用了 gin.BasicAuth
中间件。
gin.BasicAuth
:这是 Gin 框架提供的一个基本认证中间件,它接受一个 gin.Accounts
类型的映射,包含用户名和密码的信息。使用这个中间件的路由组下的所有路由都需要进行基本认证才能访问。
5
authorized.POST("admin", func(c *gin.Context) {
user := c.MustGet(gin.AuthUserKey).(string)
// Parse JSON
var json struct {
Value string `json:"value" binding:"required"`
}
if c.Bind(&json) == nil {
db[user] = json.Value
c.JSON(http.StatusOK, gin.H{"status": "ok"})
}
})
authorized.POST
:authorized
是前面创建的路由组实例,POST
方法用于注册一个 HTTP POST 请求的路由。
c.MustGet(gin.AuthUserKey)
:gin.AuthUserKey
是一个常量,用于在基本认证中间件中存储认证通过的用户名。MustGet
方法用于从 Context
中获取这个用户名,并且将其转换为字符串类型。
c.Bind(&json)
:gin.Context
的一个方法,用于将请求的 JSON 数据绑定到一个结构体上。binding:"required"
是一个标签,表示 Value
字段是必需的。如果绑定成功,就将用户输入的值存储到 db
映射中,并返回一个成功的 JSON 响应。
使用:
最开始直接再vscode的终端:
curl -X POST \ http://localhost:8080/admin \
-H 'authorization: Basic Zm9vOmJhcg==' \
-H 'content-type: application/json' \
-d '{"value":"bar"}'
结果
PowerShell 环境下,curl
命令被解析成了 Invoke-WebRequest
这个 PowerShell 命令,而 Invoke-WebRequest
并不支持像 curl
那样的参数格式。
然后使用 PowerShell 的 Invoke-WebRequest
命令
把 curl
命令转换为 Invoke-WebRequest
命令,以下是转换后的代码:
powershell
$username = "foo"
$password = "bar"
$credentials = "$($username):$($password)"
$encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($credentials))
$headers = @{
"Authorization" = "Basic $encodedCredentials"
"Content-Type" = "application/json"
}
$body = '{"value":"bar"}'
Invoke-WebRequest -Uri "http://localhost:8080/admin" -Method Post -Headers $headers -Body $body
这样就成功发送 POST 请求到 /admin
接口,为用户设置值了
于是 curl http://localhost:8080/user/foo