Gin 是 Go语言写的一个 web 框架,它具有运行速度快,分组的路由器,良好的崩溃捕获和错误处理,非常好的支持中间件和 json。总之在 Go语言开发领域是一款值得好好研究的 Web 框架,开源网址:https://github.com/gin-gonic/gin
安装 (go version 1.13+ is required):
go get -u github.com/gin-gonic/gin
创建main.go文件,代码如下:
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() //listen and serve on 0.0.0.0:8080
}
运行http server:
go run main.go
在浏览器上输入:http://localhost:8080/ping
输出结果:{"message":"pong"}
简单几行代码,就能实现一个web服务。使用gin的Default方法创建一个路由handler。然后通过HTTP方法绑定路由规则和路由函数。不同于net/http库的路由函数,gin进行了封装,把request和response都封装到gin.Context的上下文环境。最后是启动路由的Run方法监听端口。麻雀虽小,五脏俱全。当然,除了GET方法,gin也支持POST,PUT,DELETE,OPTION等常用的restful方法。
接下来就开始创建项目来学习gin的使用吧,这里给出一个典型的MVC框架大致的项目结构的例子,大家可以参考下:
├── gin #项目根目录
│ ├── conf #项目配置文件目录
│ └── config.toml #大家可以选择自己熟悉的配置文件管理工具包例如:toml、xml等等
│ ├── router #路由目录
│ └── router.go
│ ├── middlewares #中间件目录
│ └── CorsMiddleware.go
│ ├── controllers #控制器目录(MVC)
│ └── IndexController.go
│ ├── services #服务层目录,这里把DAO逻辑也写入其中,如果分开也可以
│ └── IndexService.go
│ ├── models #模型目录
│ └── UserModel.go
│ └── FoodModel.go
│ ├── databases #数据库初始化目录
│ └── mysql.go
│ ├── sessions #session初始化目录
│ └── session.go
│ ├── static #静态资源目录,包括Js,css,jpg等等
│ └── css
│ └── js
│ └── images
│ ├── templates #模板目录
│ └── index.html
│ └── header.html
│ └── test.html
└── main.go
常见访问数据库模块gorm,xorm等。
gin的路由来自httprouter库。因此httprouter具有的功能,gin也具有,不过gin不支持路由正则表达式:
func main(){
router := gin.Default()
router.GET("/user/:name", func(c *gin.Context) {
name := c.Param("name")
c.String(http.StatusOK, "Hello %s", name)
})
}
冒号:加上一个参数名组成路由参数。可以使用c.Params的方法读取其值。当然这个值是字串string。诸如/user/admin,和/user/hello都可以匹配,而/user/和/user/admin/不会被匹配。
curl http://127.0.0.1:8080/user/admin
Hello admin%
curl http://127.0.0.1:8080/user/admin/
404 page not found%
curl http://127.0.0.1:8080/user/
404 page not found%
除了:,gin还提供了*
号处理参数,*
号能匹配的规则就更多。
func main(){
router := gin.Default()
router.GET("/user/:name/*action", func(c *gin.Context) {
name := c.Param("name")
action := c.Param("action")
message := name + " is " + action
c.String(http.StatusOK, message)
})
}
访问效果如下
curl http://127.0.0.1:8080/user/admin/
admin is /%
curl http://127.0.0.1:8080/user/admin/中国
admin is /中国%
web提供的服务通常是client和server的交互。其中客户端向服务器发送请求,除了路由参数,其他的参数无非两种,查询字符串query string和报文体body参数。所谓query string,即路由用,用?以后连接的key1=value2&key2=value2的形式的参数。当然这个key-value是经过urlencode编码。
对于参数的处理,经常会出现参数不存在的情况,对于是否提供默认值,gin也考虑了,并且给出了一个优雅的方案:
func main(){
router := gin.Default()
router.GET("/welcome", func(c *gin.Context) {
firstname := c.DefaultQuery("firstname", "Guest")
lastname := c.Query("lastname")
c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
})
router.Run()
}
使用c.DefaultQuery方法读取参数,其中当参数不存在的时候,提供一个默认值。使用Query方法读取正常参数,当参数不存在的时候,返回空字串:
curl http://127.0.0.1:8080/welcome
Hello Guest %
curl http://127.0.0.1:8080/welcome\?firstname\=中国
Hello 中国 %
curl http://127.0.0.1:8080/welcome\?firstname\=中国\&lastname\=天朝
Hello 中国 天朝%
curl http://127.0.0.1:8080/welcome\?firstname\=\&lastname\=天朝
Hello 天朝%
curl http://127.0.0.1:8080/welcome\?firstname\=%E4%B8%AD%E5%9B%BD
Hello 中国 %
之所以使用中文,是为了说明urlencode。注意,当firstname为空字串的时候,并不会使用默认的Guest值,空值也是值,DefaultQuery只作用于key不存在的时候,提供默认值。
http的报文体传输数据就比query string稍微复杂一点,常见的格式就有四种。例如application/json
,application/x-www-form-urlencoded
, application/xml
和multipart/form-data
。后面一个主要用于图片上传。json格式的很好理解,urlencode其实也不难,无非就是把query string的内容,放到了body体里,同样也需要urlencode。默认情况下,c.PostFROM解析的是x-www-form-urlencoded
或from-data
的参数。
func main(){
router := gin.Default()
router.POST("/form_post", func(c *gin.Context) {
message := c.PostForm("message")
nick := c.DefaultPostForm("nick", "anonymous")
c.JSON(http.StatusOK, gin.H{
"status": gin.H{
"status_code": http.StatusOK,
"status": "ok",
},
"message": message,
"nick": nick,
})
})
}
与get处理query参数一样,post方法也提供了处理默认参数的情况。同理,如果参数不存在,将会得到空字串。
curl -X POST http://127.0.0.1:8080/form_post -H "Content-Type:application/x-www-form-urlencoded" -d "message=hello&nick=admin" | python -m json.tool
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 104 100 79 100 25 48555 15365 --:--:-- --:--:-- --:--:-- 79000
{
"message": "hello",
"nick": "admin",
"status": {
"status": "ok",
"status_code": 200
}
}
前面我们使用c.String返回响应,顾名思义则返回string类型。content-type是plain或者text。调用c.JSON则返回json数据。其中gin.H封装了生成json的方式,是一个强大的工具。使用golang可以像动态语言一样写字面量的json,对于嵌套json的实现,嵌套gin.H即可。
发送数据给服务端,并不是post方法才行,put方法一样也可以。同时querystring和body也不是分开的,两个同时发送也可以:
func main(){
router := gin.Default()
router.PUT("/post", func(c *gin.Context) {
id := c.Query("id")
page := c.DefaultQuery("page", "0")
name := c.PostForm("name")
message := c.PostForm("message")
fmt.Printf("id: %s; page: %s; name: %s; message: %s \n", id, page, name, message)
c.JSON(http.StatusOK, gin.H{
"status_code": http.StatusOK,
})
})
}
上面的例子,展示了同时使用查询字串和body参数发送数据给服务器。
出处:www.l1mn.com
原文标题:golang gin框架入门教程
原文地址:https://www.l1mn.com/p/ytzou4.html
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
Copyright © L1MN.COM 联系方式:l1mnfw@163.com