1. Gin简介
Gin
是一个golang
的微框架,封装比较优雅,API
友好,源码注释比较明确。具有快速灵活,容错方便等特点。其实对于golang
而言,web
框架的依赖要远比Python
,Java
之类的要小。自身的net/http
足够简单,性能也非常不错。框架更像是一些常用函数或者工具的集合。借助框架开发,不仅可以省去很多常用的封装带来的时间,也有助于团队的编码风格和形成规范。
2. Gin安装
1 2 3 4 5 6 7 8 9
| #创建目录 mkdir gin
#创建mod cd gin go mod init gin
#下载gin go get -u github.com/gin-gonic/gin
|
3. 案例
3.1 案例一
写一个最简单的gin框架
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package main
import ( "fmt" "github.com/gin-gonic/gin" )
func main() { r := gin.Default() r.GET("/", func(c *gin.Context) { c.String(200, "hello world") }) fmt.Println("http://127.0.0.1:8000") r.Run(":8000") }
|
3.2 案例二
写一个最简单的无参路由:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package main
import "github.com/gin-gonic/gin"
func main() { r := gin.Default()
r.GET("/hello", hello) r.Run(":8000") }
func hello(c *gin.Context) { c.String(200, "hello") }
|
3.3 案例三
API参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package main
import ( "fmt" "github.com/gin-gonic/gin" )
func main() { r := gin.Default()
r.GET("/product/:id", GetProduct) r.Run(":8000") }
func GetProduct(c *gin.Context) { ProductId := c.Param("id") fmt.Println(ProductId, "------") c.String(200, "API params") }
|
3.4 案例四
url参数
url传参: http://127.0.0.1:8000/user?id=20&name=luck
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| package main
import ( "fmt"
"github.com/gin-gonic/gin" )
func main() { r := gin.Default()
r.GET("/user", Getuser)
r.Run(":8000") }
func Getuser(c *gin.Context) { name := c.Query("name")
name2 := c.DefaultQuery("name", "default") fmt.Println("获取的用户名---》", name, name2) c.String(200, "URL params") }
|
3.5 案例五
shouldBind
参数绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| package main
import ( "fmt" "github.com/gin-gonic/gin" )
func main() { r := gin.Default()
r.POST("/login/", logfunc) r.Run(":8000") }
type Login struct { Username string `json:"username" binding:"required"` Password string `json:"password"` }
func logfunc(c *gin.Context) { var login Login if err := c.ShouldBind(&login); err != nil { fmt.Println(err) c.String(200, "参数校验错误") } fmt.Println(login.Username, login.Password) c.String(200, "success") }
|
3.6 案例六
响应返回
响应string
字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package main
import "github.com/gin-gonic/gin"
func main() { r := gin.Default() r.GET("/response", responsefunc) r.Run(":8000") }
func responsefunc(c *gin.Context) { c.String(200, "响应一个string字符串") }
|
响应json
数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package main
import "github.com/gin-gonic/gin"
func main() { r := gin.Default() r.GET("/response/json", responsefunc) r.Run(":8000") }
func responsefunc(c *gin.Context) { c.JSON(200, gin.H{ "msg": "sucess", "code": 1001, }) }
|
路由分发
一个项目往往有非常多的模块,如果全部写在一起会导致代码结构混乱,不利于后续的扩展
按照大的模块,每个模块都有自己的路由,主路由可以在main.go
中进行注册
main.go
1 2 3 4 5 6 7 8 9 10 11 12 13
| package main
import ( "github.com/gin-gonic/gin" "route/routers" )
func main() { r := gin.Default() routers.Users(r) routers.Books(r) r.Run(":8000") }
|
bookinfo.go
1 2 3 4 5 6 7 8 9 10 11
| package routers
import "github.com/gin-gonic/gin"
func Books(r *gin.Engine) { r.GET("/book", BooksHandler) }
func BooksHandler(c *gin.Context) { c.String(200, "书籍模块") }
|
userinfo.go
1 2 3 4 5 6 7 8 9 10 11
| package routers
import "github.com/gin-gonic/gin"
func Users(r *gin.Engine) { r.GET("/user", UsersHandler) }
func UsersHandler(c *gin.Context) { c.String(200, "用户模块") }
|