github地址: https://github.com/gin-gonic/gin
初体验
安装: $ go get -u github.com/gin-gonic/gin
简单实例:
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
_ = r.Run()
}
启动一个HTTP服务进程,默认监听在8080端口
gin.Default实例化一个GIN对象
该对象的GET方法,参数表中分别是路径和多个handler
// GET is a shortcut for router.Handle("GET", path, handle).
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle(http.MethodGet, relativePath, handlers)
}
handlerFunc的具体类型:
// HandlerFunc defines the handler used by gin middleware as return value.
type HandlerFunc func(*Context)
按照这种格式定义函数:
func pong(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
}
func main() {
r := gin.Default()
r.GET("/ping", pong)
_ = r.Run(":9090")
}
同时在Run中可以指定端口号,不使用默认端口号
gin.H是一个map:
// H is a shortcut for map[string]interface{}
type H map[string]any
所以如下方法同理:
func pong(c *gin.Context) {
var m = map[string]string{
"message": "pong",
}
c.JSON(http.StatusOK, m)
}
初始化路由
除了上述的gin.Default方法,还可以使用gin.New来创建路由,前者会开启两个中间件,分别是Logger和Recovery:
// Default returns an Engine instance with the Logger and Recovery middleware already attached.
func Default() *Engine {
debugPrintWARNINGDefault()
engine := New()
engine.Use(Logger(), Recovery())
return engine
}
Logger负责日志,Recovery负责异常处理
只使用New方法便不会开启这两个功能
配置路由:
func getting(c *gin.Context) {
c.JSON(http.StatusOK,gin.H{
"message":"getting",
})
}
func posting(c *gin.Context) {
c.JSON(http.StatusOK,gin.H{
"message":"posting",
})
}
func main() {
router := gin.Default()
router.GET("/get", getting)
router.GET("/post", posting)
_ = router.Run()
}
路由分组
使用Group方法进行路由分组
func main() {
router := gin.Default()
router.GET("/goods/list",goodsList)
router.POST("/goods/add",createGoods)
_ = router.Run()
}
使用路由分组改写,与上方同理:
func main() {
router := gin.Default()
goodsGroup := router.Group("/goods")
goodsGroup.GET("/list", goodsList)
goodsGroup.GET("/add", createGoods)
_ = router.Run()
}
获取参数
带参数URL:
func main() {
router := gin.Default()
goodsGroup := router.Group("/goods")
goodsGroup.GET("/", goodsList)
goodsGroup.POST("", createGoods)
goodsGroup.GET("/:id", goodsDetail)
_ = router.Run()
}
func createGoods(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{})
}
func goodsDetail(c *gin.Context) {
id := c.Param("id")
c.JSON(http.StatusOK, gin.H{
"id": id,
})
}
func goodsList(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "list",
})
}
这里id会作为参数,例如访问http://localhost:8080/1
,id便等于1
如下可扩展为多参数:
func goodsDetail(c *gin.Context) {
id := c.Param("id")
action := c.Param("action")
c.JSON(http.StatusOK, gin.H{
"id": id,
"action": action,
})
}
访问http://localhost:8080/goods/1/detail
,便会携带两个参数
获取GET/POST传参:
func main() {
router := gin.Default()
router.GET("/welcome", welcome)
router.POST("/login", login)
router.POST("/post", getPost)
_ = router.Run()
}
// 获取GET传参
func welcome(c *gin.Context) {
firstName := c.DefaultQuery("firstname", "unknown")
lastName := c.DefaultQuery("lastname", "unknown")
c.JSON(http.StatusOK, gin.H{
"first_name": firstName,
"last_name": lastName,
})
}
// 获取POST传参
func login(c *gin.Context) {
username := c.DefaultPostForm("username", "test")
password := c.DefaultPostForm("password", "test")
c.JSON(http.StatusOK, gin.H{
"username": username,
"password": password,
})
}
// 混合获取参数
func getPost(c *gin.Context) {
// 获取GET参数
id := c.Query("id")
page := c.DefaultQuery("page", "0")
// 获取POST参数
name := c.PostForm("name")
message := c.DefaultPostForm("message", "")
c.JSON(http.StatusOK, gin.H{
"id": id,
"page": page,
"name": name,
"message": message,
})
}
使用如下python代码进行测试:
import requests
url = "http://127.0.0.1:8080/post"
data = {
"name": "David",
"message": "test",
}
params = {
"id": 1,
"page": 2
}
resp = requests.post(url,params=params,data=data)
print(resp.text)
JSON渲染
将结构体序列化为JSON字符串
func main() {
router := gin.Default()
router.GET("/moreJSON", moreJSON)
_ = router.Run()
}
func moreJSON(c *gin.Context) {
var message struct {
Name string `json:"name"`
Message string
Number int
}
message.Name = "David"
message.Message = "json test"
message.Number = 20
c.JSON(http.StatusOK, message)
}
表单验证
GIN提供了两种方法来进行表单验证: Must Bind / Should Bind,其中要搭配validate
接收表单请求,获取用户名和密码:
type LoginForm struct {
User string `json:"user" binding:"required,min=3,max=20"`
Password string `json:"password" binding:"required"`
}
type SignUpForm struct {
Age uint8 `json:"age" binding:"gte=1,lte=130"`
Name string `json:"name" binding:"required,min=3"`
Email string `json:"email" binding:"required,email"`
Password string `json:"password" binding:"required"`
RePassword string `json:"repassword" binding:"required,eqfield=Password"`
}
func main() {
router := gin.Default()
router.POST("/loginJSON", func(c *gin.Context) {
var loginForm LoginForm
if err := c.ShouldBind(&loginForm); err != nil {
fmt.Println(err.Error())
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
return
}
c.JSON(http.StatusOK, gin.H{
"msg": "login",
})
})
router.POST("/signup", func(c *gin.Context) {
var signupForm SignUpForm
if err := c.ShouldBind(&signupForm); err != nil {
fmt.Println(err.Error())
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
return
}
})
_ = router.Run()
}
使用POST请求发送JSON数据
登录:
{
"user":"David",
"password":"123"
}
注册:
{
"name":"David",
"age":12,
"email" :"[email protected]",
"password":"123",
"re_password":"123"
}
标签:http,入门,框架,GET,gin,JSON,func,router,Gin
From: https://www.cnblogs.com/N3ptune/p/16972521.html