Go Gin框架学习
<p><span style="font-size: 15px"><strong>什么是Gin?</strong></span></p><p> Gin 是一个用 Go (Golang) 编写的 HTTP web 框架。 它是一个类似于 martini 但拥有更好性能的 API 框架, 多亏了 httprouter,速度提高了近 40 倍。具有良好的性能和生产力。</p>
<p> 而且封装比较优雅,API友好,源码注释比较明确,具有快速灵活,容错方便等特点</p>
<p> 对于golang而言,web框架的依赖要远比Python,Java之类的要小。自身的net/http足够简单,性能也非常不错</p>
<p> 文档:https://gin-gonic.com/zh-cn/docs/</p>
<p> </p>
<p> </p>
<p><span style="font-size: 15px"><strong>Gin安装使用:</strong></span></p>
<p> 要求:Go 1.13 及以上版本</p>
<p> 要安装Gin软件包,您需要安装Go并首先设置Go工作区。</p>
<p> 1、首先需要安装Go(需要1.13+版本),然后可以使用下面的Go命令安装Gin。</p>
<p> <strong>go get -u github.com/gin-gonic/gin</strong></p>
<p> 2、将 gin 引入到代码中:</p>
<p> <strong> import "github.com/gin-gonic/gin"</strong></p>
<p> 3、(可选)如果使用诸如 http.StatusOK 之类的常量,则需要引入 net/http 包:</p>
<p> <strong>import "net/http"</strong> </p>
<p> </p>
<p><span style="font-size: 15px"><strong>快速开始:</strong></span></p>
<p><span style="font-size: 14px"> 1、创建一个名为GinDemo.go的文件, touch GinDemo.go<strong><br></strong></span></p>
<p><span style="font-size: 14px"> 2、GinDemo.go代码如下:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">package main
import </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">github.com/gin-gonic/gin</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
func main() {
router :</span>=<span style="color: rgba(0, 0, 0, 1)"> gin.Default()
router.GET(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/ping</span><span style="color: rgba(128, 0, 0, 1)">"</span>, func(c *<span style="color: rgba(0, 0, 0, 1)">gin.Context) {
c.JSON(</span><span style="color: rgba(128, 0, 128, 1)">200</span><span style="color: rgba(0, 0, 0, 1)">, gin.H{
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">message</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">pong</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
})
})
router.Run() </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 监听并在 0.0.0.0:8080 上启动服务</span>
}</pre>
</div>
<p> 3、执行 go run GinDemo.go 命令来运行代码:</p>
<div class="cnblogs_code">
<pre># 运行 example.go 并且在浏览器中访问 <span style="color: rgba(128, 0, 128, 1)">0.0</span>.<span style="color: rgba(128, 0, 128, 1)">0.0</span>:<span style="color: rgba(128, 0, 128, 1)">8080</span>/<span style="color: rgba(0, 0, 0, 1)">ping
$ go run example.go</span></pre>
</div>
<p> 启动日志:</p>
<div class="cnblogs_code">
<pre> Creating an Engine instance with the Logger and Recovery middleware already attached.
Running <span style="color: rgba(0, 0, 255, 1)">in</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">debug</span><span style="color: rgba(128, 0, 0, 1)">"</span> mode. Switch to <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">release</span><span style="color: rgba(128, 0, 0, 1)">"</span> mode <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> production.
</span>- <span style="color: rgba(0, 0, 255, 1)">using</span> env: export GIN_MODE=<span style="color: rgba(0, 0, 0, 1)">release
</span>- <span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> code: gin.SetMode(gin.ReleaseMode)
GET / --> main.main.func1 (<span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)"> handlers)
You trusted all proxies, <span style="color: rgba(0, 0, 255, 1)">this</span> <span style="color: rgba(0, 0, 255, 1)">is</span> NOT safe. We recommend you to <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)"> a value.
Please check https:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.</span>
Listening and serving HTTP on :<span style="color: rgba(128, 0, 128, 1)">8000</span></pre>
</div>
<p> </p>
<p> </p>
<p> </p>
<p><span style="font-size: 15px"><strong>Gin路由:</strong></span></p>
<p><strong> 基本路由:</strong>gin框架中采用的路由是基于httprouter做的,也支持Restful风格的API</p>
<p> API参数:可以通过Context的Param方法来获取API参数</p>
<p> URL参数:可以通过DefaultQuery()或Query()方法获取,DefaultQuery()若参数不存在,返回默认值,Query()若不存在,返回空串</p>
<p> 表单参数:表单传输为post请求,http常见的传输格式为四种:</p>
<p> application/json</p>
<p> application/x-www-form-urlencoded</p>
<p> application/xml</p>
<p> application/form-data</p>
<p> 表单参数可以通过PostFrom()方法获取,该方法默认解析的是x-www-form-urlencoded或from-data格式的参数</p>
<p> <strong> routes group:</strong>routes group是为了管理一些相同的URL</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">func main() {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 1.创建路由
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 默认使用了2个中间件Logger(), Recovery()</span>
r :=<span style="color: rgba(0, 0, 0, 1)"> gin.Default()
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 路由组1 ,处理GET请求</span>
v1 := r.Group(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/v1</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> {} 是书写规范</span>
<span style="color: rgba(0, 0, 0, 1)"> {
v1.GET(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/login</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, login)
v1.GET(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">submit</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, submit)
}
v2 :</span>= r.Group(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/v2</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
{
v2.POST(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/login</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, login)
v2.POST(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/submit</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, submit)
}
r.Run(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">:8000</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
}</span></pre>
</div>
<p> </p>
<p> 运行main方法即可启动gin项目:go run main.go</p>
<p> </p>
<p><strong>Jsoniter:</strong></p>
<p> Gin 使用 encoding/json 作为默认的 json 包,但是你可以在编译中使用标签将其修改为 jsoniter。</p>
<p> go build -tags=jsoniter</p>
<p> </p>
<p> </p>
<p> </p>
<p><span style="font-size: 15px"><strong>Goland新建Gin项目:</strong></span></p>
<p> 1、新建go modules,File-New-Project-Go modules</p>
<p><img src="https://img2022.cnblogs.com/blog/1238257/202206/1238257-20220606151941117-116756375.png"></p>
<p> 此时项目中只有一个go.mod文件,类似于Java中Maven的pom.xml</p>
<p> 2、下载Gin框架依赖</p>
<p> 命令行进入项目目录中,下载并安装gin:go get -u github.com/gin-gonic/gin</p>
<p> 此时go.mod:</p>
<pre class="language-go highlighter-hljs"><code>module filter-search
go 1.16
require (
github.com/gin-gonic/gin v1.8.0 // indirect
github.com/go-playground/validator/v10 v10.11.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/net v0.0.0-20220531201128-c960675eff93 // indirect
)</code></pre>
<p> 3、新建main.go文件</p>
<p> 项目根目录新建cmd文件夹,cmd目录下新建 main.go</p>
<pre class="language-go highlighter-hljs"><code>package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
router := gin.Default()
// 路由
router.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
// 路由请求到处理器
// router.GET("/search",handler)
// 指定服务端口
server := &http.Server{
Addr: ":8080",
Handler: router,
}
// 监听并启动服务
server.ListenAndServe()
}</code></pre>
<p> 4、go run main.go 或者右键 go build filter-search</p>
<p> 访问:http://localhost:8080/ping</p>
<p> 5、新建目录</p>
<p> internal目录,用于存放业务实现代码(类似于Java中的src),其下根据具体子业务新建子目录。handler放在此目录下</p>
<p> init目录,用于存放项目启动即初始化的逻辑代码</p>
<p> deploy目录存放部署相关代码</p>
<p> </p>
<p> </p>
<p><span style="font-size: 15px"><strong>Gin日志:</strong></span></p>
<p><span style="font-size: 15px"><strong> </strong><span style="font-size: 14px">1、如何记录日志</span></span></p>
<pre class="language-go highlighter-hljs"><code>func main() {
// 禁用控制台颜色,将日志写入文件时不需要控制台颜色。
gin.DisableConsoleColor()
// 记录到文件。
f, _ := os.Create("gin.log")
gin.DefaultWriter = io.MultiWriter(f)
// 如果需要同时将日志写入文件和控制台,请使用以下代码。
// gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
router := gin.Default()
router.GET("/ping", func(c *gin.Context) {
c.String(200, "pong")
})
router.Run(":8080")
}</code></pre>
<p> 2、请求路由日志格式</p>
<p> 默认的请求路由日志格式:</p>
<pre class="language-go highlighter-hljs"><code> POST /foo --> main.main.func1 (3 handlers)
GET /bar --> main.main.func2 (3 handlers)
GET /status --> main.main.func3 (3 handlers)</code></pre>
<p> 如果你想要以指定的格式(例如 JSON,key values 或其他格式)记录信息,则可以使用 gin.DebugPrintRouteFunc 指定格式。</p>
<p> 在下面的示例中,我们使用标准日志包记录所有路由,但你可以使用其他满足你需求的日志工具 </p>
<pre class="language-go highlighter-hljs"><code> r := gin.Default()
gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
}</code></pre>
<p> 3、自定义日志输出文件</p>
<pre class="language-go highlighter-hljs"><code>func main() {
router := gin.New()
// LoggerWithFormatter 中间件会写入日志到 gin.DefaultWriter
// 默认 gin.DefaultWriter = os.Stdout
router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
// 你的自定义格式
return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
param.ClientIP,
param.TimeStamp.Format(time.RFC1123),
param.Method,
param.Path,
param.Request.Proto,
param.StatusCode,
param.Latency,
param.Request.UserAgent(),
param.ErrorMessage,
)
}))
router.Use(gin.Recovery())
router.GET("/ping", func(c *gin.Context) {
c.String(200, "pong")
})
router.Run(":8080")
}</code></pre>
<p> </p>
<p> </p>
<p>END.</p><br><br>
来源:https://www.cnblogs.com/yangyongjie/p/15100300.html
頁:
[1]