这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
安装:
go get -u github.com/gin-gonic/gin
go在1.13版本后,默认开启了: GOSUMDB=sum.golang.org 而这个网址sum.golang.org 在国内是无法访问,故需要关闭 go env -w GO111MODULE=on
更换国内源
go env -w GOPROXY=mirrors.aliyun.com/goproxy/,di…
import "github.com/gin-gonic/gin"
r := gin.Default()
Gin实例创建路由:(使用匿名函数来处理GET请求,当请求到达“/hello”路径时,返回一个JSON响应。)
1.Gin 支持 GET、POST、PUT、PATCH、DELETE、OPTIONS 等请求类型。
2.可通过 *gin.Context 的 Param 函数获取请求 Path 中的参数,Path 路径中参数以:开头,如:/user/:name,能够匹配路径 /user/xx。
3.可通过 *gin.Context 的 Query 函数获取参数,如:/user?name=xcbeyond。
4.Gin 提供了路由分组的能力,方便管理分组管理路由,将具有相同路由 URL 前缀的进行分类处理,常见于不同版本的分组,如:/api/v1、/api/v1。也支持多级分组。
5.路由支持拆分 。
r.GET("/hello", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "Hello, World!",
})
})
请求和响应:
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")
if token == "" {
c.AbortWithStatus(401)
} else {
c.Next()
}
}
}
gin特点:
- 零分配路由。
- 最快的 http 路由器和框架。
- 完整的单元测试支持。
- API 冻结,新版本的发布不会破坏你的代码。
- Gin 项目可以轻松部署在任何云提供商上。
集成Swagger
$ go get github.com/swaggo/swag/cmd/swag
安装gin-swagger
$ go get -u github.com/swaggo/gin-swagger
$ go get -u github.com/swaggo/gin-swagger/swaggerFiles
- 引入生成的docs包
- 在具体接口上根据规范swag编写接口描述
- 在路由中进行引入
- 再次执行swag init 更新接口
- 运行应用后,浏览器访问:http://localhost:8887/swagger/index.html
package main
import (
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
_ "github.com/swaggo/gin-swagger/example/basic/docs" // docs is generated by Swag CLI, you have to import it.
)
func main() {
r := gin.New()
url := ginSwagger.URL("http://localhost:8080/swagger/doc.json") // The url pointing to API definition
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, url))
r.Run()
}
实例引用:(视频的上传与下载接口的实现)
package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.POST("/upload", func(c *gin.Context) {
file, header, err := c.Request.FormFile("file")
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("文件上传失败: %s", err.Error()))
return
}
defer file.Close()
filename := header.Filename
out, err := os.Create("videos/" + filename)
if err != nil {
log.Fatal(err)
}
defer out.Close()
_, err = io.Copy(out, file)
if err != nil {
log.Fatal(err)
}
c.String(http.StatusOK, fmt.Sprintf("文件 %s 上传成功", filename))
})
r.GET("/download/:name", func(c *gin.Context) {
filename := c.Param("name")
file, err := os.Open("videos/" + filename)
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("文件 %s 下载失败: %s", filename, err.Error()))
return
}
defer file.Close()
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
c.Header("Content-Type", "application/octet-stream")
c.File("videos/" + filename)
})
r.Run(":8080")
}