1. Gin基本使用
1.1 Gin入门
- Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,具有快速灵活,容错方便等特点
- 对于Golang而言,web框架的依赖要远比Python,Java之类要小,自身的net/http足够简单,性能也非常不错
- 借助框架开发,不仅可以省去很多常用的封装带来的时间,也有助于团队的编码风格和形成规范.
1.2 安装
要安装Gin 软件包,需要先安装GO并设置Go工作区.
- 首先需要安装GO,然后可以使用GO命令安装Gin.在go.mod同级目录执行以下命令.
go get -u github.com/gin-gonic/gin
3.Gin入门与源码
一共需要3步.
- 创建路由
- 路由绑定
- 启动监听
func main() {
// 1. 创建路由
r := gin.Default()
// 2. 路由绑定
r.GET("/", func(c *gin.Context) {
c.String(200, "ok")
})
// 3. 启动监听
fmt.Println("http://192.168.31.1:8080")
r.Run(":8080")
}
1.3 gin核心概念
- Engine 容器对象,整个框架基础
- Engine.trees 负责存储路由和handle方法的映射,采用类似字典树的结构
- Engine.RouterGroup 其中Handlers存储着所有中间件
- Context上下文对象,负责处理请求和回应,其中handlers是存储处理请求时中间件和处理方法的.
2. gin 路由
2.1 无参路由
不传递任何数据
func main() {
// 1. 定义路由
r := gin.Default()
// 2. 定义路由
r.GET("/hello", HelloHandler)
// 3. 启动监听
fmt.Println("http://192.168.31.1:8080/hello")
r.Run(":8080")
}
func HelloHandler(c *gin.Context) {
c.String(200, "hello world")
}
2.2 Api传参
func main() {
// 1. 定义
r := gin.Default()
r.GET("/book/:id", GetBookHandler)
fmt.Println("http://localhost:8080/")
r.Run(":8080")
}
func GetBookHandler(c *gin.Context) {
bookID := c.Param("id")
fmt.Println(bookID, "------->")
book := "你找的书:" + bookID + "已经找到\n"
c.String(200, book)
}
2.3 Url传参
func main() {
r := gin.Default()
r.GET("/user", UrlGetHandler)
fmt.Println("http://192.168.31.1:8080/")
r.Run(":8080")
}
func UrlGetHandler(c *gin.Context) {
username := c.Query("username")
password := c.Query("password")
output := "你输入的用户名是:" + username + " 密码是:" + password
c.String(200, output)
}
设置默认值
func main() {
r := gin.Default()
r.GET("/user", UrlGetHandler)
fmt.Println("http://192.168.31.1:8080/")
r.Run(":8080")
}
func UrlGetHandler(c *gin.Context) {
username := c.Query("username")
//password := c.Query("password")
password := c.DefaultQuery("password", "你没有输入密码")
output := "你输入的用户名是:" + username + " 密码是:" + password
c.String(200, output)
}
如果这里没有传值就会用默认值替代
如果传入值,那么就用传入的值.
2.4 shouldBind
用来解析Post请求中复杂的Json数据
func main() {
r := gin.Default()
r.POST("/user/login", LoginHandler)
r.Run(":8080")
}
type Login struct {
Username string `json:"username"`
Password string `json:"password"`
}
func LoginHandler(c *gin.Context) {
var login Login
if err := c.ShouldBind(&login); err != nil {
c.String(400, "err")
return
}
Code := login.Username + " Login Succeeded!"
c.String(200, Code)
}
也可以将某个参数设为必须
func main() {
r := gin.Default()
r.POST("/user/login", LoginHandler)
r.Run(":8080")
}
type Login struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}
func LoginHandler(c *gin.Context) {
var login Login
if err := c.ShouldBind(&login); err != nil {
fmt.Println(err)
c.String(400, "err")
return
}
Code := login.Username + " Login Succeeded!"
c.String(200, Code)
}
当没有传该参数时就会报错
3. 数据返回Response
3.1 String字符串返回
func main() {
r := gin.Default()
r.GET("/response", ResponseHandler)
r.Run(":8080")
}
func ResponseHandler(c *gin.Context) {
msg := "success response"
c.String(200, msg)
}
3.2 返回Json数据
func main() {
r := gin.Default()
r.GET("/response", JsonHandler)
r.Run(":8080")
}
func JsonHandler(c *gin.Context) {
type Data struct {
Msg string `json:"msg"`
Code int `json:"code"`
}
d := Data{
Msg: "success",
Code: 200,
}
c.JSON(200, d)
}
3.3 直接通过gin.H返回
直接用gin.H将json数据进行返回,返回效果和上面效果一样
func JsonHandler(c *gin.Context) {
c.JSON(200, gin.H{
"msg": "success",
"code": 200,
})
}
3.4 路由重定向
func main() {
r := gin.Default()
r.GET("/response/json", JsonHandler)
r.GET("/response/baidu", ResponseRedirHandler)
r.Run(":8080")
}
func ResponseHandler(c *gin.Context) {
msg := "success response"
c.String(200, msg)
}
func JsonHandler(c *gin.Context) {
c.JSON(200, gin.H{
"msg": "success",
"code": 200,
})
}
func ResponseRedirHandler(c *gin.Context) {
c.Redirect(302, "https://www.baidu.com")
}
4. 路由分发
一个项目有非常多的模块,每个模块维护自己的路由.主路由在main.go中进行注册
初始化项目
go mod init demo_route_layer // 初始化项目
go mod tidy // 更新项目中使用的模块
go get github.com/gin-gonic/gin // 下载go模块
main.go
import (
"demo_route_layer/routers" // 导入本地模块
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// 注册路由
routers.LoadUsers(r)
routers.LoadBook(r)
r.Run(":8080")
}
routers/users.go
// 分层注册路由
func LoadUsers(r *gin.Engine) {
r.GET("/user", UserHandler)
}
func UserHandler(c *gin.Context) {
c.String(200, "用户模块分发")
}
routers/book
import "github.com/gin-gonic/gin"
func LoadBook(r *gin.Engine) {
r.GET("/book", BooksHandler)
}
func BooksHandler(c *gin.Context) {
c.String(200, "图书模块返回")
}