gin入门
【摘要】 Gin 是一个用 Go 语言编写的高性能 Web 框架,它提供了丰富的功能和灵活的配置选项,适用于构建高效、可扩展的 Web 应用程序。下载gin可以使用go get -u github.com/gin-gonic/gin在 main.go 文件中编写一个简单的 Gin 应用程序package mainimport ( "net/http" "github.com/gin-gon...
Gin 是一个用 Go 语言编写的高性能 Web 框架,它提供了丰富的功能和灵活的配置选项,适用于构建高效、可扩展的 Web 应用程序。
下载gin可以使用
go get -u github.com/gin-gonic/gin
在 main.go
文件中编写一个简单的 Gin 应用程序
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
// 创建一个默认的路由引擎
r := gin.Default()
// 定义一个简单的路由
r.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "Hello, Gin!")
})
// 启动 HTTP 服务,默认监听 8080 端口
r.Run()
}
访问http://localhost:8080 可以看到 Hello,Gin!
可以设置路由组
r := gin.Default()
// 创建一个用户相关的路由组
userGroup := r.Group("/user")
{
userGroup.GET("/profile", getUserProfile)
userGroup.POST("/login", userLogin)
userGroup.POST("/register", userRegister)
}
中间件是处理请求的函数,可以用于日志记录、认证、错误处理等。Gin 框架提供了丰富的中间件支持。
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func Logger() gin.HandlerFunc {
return func(c *gin.Context) {
// 在请求处理之前记录请求信息
c.Writer.Header().Set("X-My-Header", "my-value")
c.Next()
// 在请求处理之后记录响应信息
c.Writer.Header().Set("X-My-Response-Header", "my-response-value")
}
}
func Recovery() gin.HandlerFunc {
return func(c *gin.Context) {
defer func() {
if err := recover(); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal server error"})
}
}()
c.Next()
}
}
func main() {
r := gin.Default()
// 使用自定义中间件
r.Use(Logger(), Recovery())
r.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "Hello, Gin!")
})
r.Run()
}
这个其实和nodejs的koa,express的中间件差不多,都是洋葱模型。
当访问不存在的路由时也可以定义返回内容
r.NoRoute(func(c *gin.Context) {
c.JSON(http.StatusNotFound, gin.H{"code": "404", "message": "Page not found"})
})
当需要接收参数时可以使用结构体
type User struct {
ID int `json:"id"`
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
Age int `json:"age"`
}
// 定义一个处理器函数
func createUser(c *gin.Context) {
var user User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
fmt.Println(user.Username)
// 模拟用户创建
user.ID = 1
c.JSON(http.StatusCreated, user)
}
// 定义一个处理器函数
func getUser(c *gin.Context) {
id := c.Param("id")
// 模拟从数据库中获取用户
fmt.Println(id)
user := User{ID: 1, Username: "testuser", Password: "testpassword", Age: 25}
c.JSON(http.StatusOK, user)
}
// 定义一个处理器函数
func updateUser(c *gin.Context) {
id := c.Param("id")
var user User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// 模拟更新用户
c.JSON(http.StatusOK, gin.H{"message": "User updated", "id": id, "user": user})
}
// 定义一个处理器函数
func deleteUser(c *gin.Context) {
id := c.Param("id")
// 模拟删除用户
c.JSON(http.StatusOK, gin.H{"message": "User deleted", "id": id})
}
gin的原理是使用了前缀树,通过压缩公共前缀来节省空间,提高查询效率。例如,路径 /ping
和 /ping/hello
可以共享前缀 /ping
,从而减少节点数量。每个路由节点会挂载一个函数链,链的前面部分是中间件函数,后面部分是业务处理函数。gin.Context作为请求/响应信息的统一容器,通过sync.Pool高效复用
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
// Engine 结构体中包含一个 sync.Pool 用于复用 Context 对象
type Engine struct {
pool sync.Pool
// 其他字段...
}
// ServeHTTP 实现 http.Handler 接口
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// 从对象池中获取一个 Context 对象
c := engine.pool.Get().(*gin.Context)
c.writermem.reset(w)
c.Request = req
// 重置 Context 对象的状态
c.reset()
// 处理 HTTP 请求
engine.handleHTTPRequest(c)
// 将处理过的 Context 对象放回对象池
engine.pool.Put(c)
}
// handleHTTPRequest 处理 HTTP 请求
func (engine *Engine) handleHTTPRequest(c *gin.Context) {
// 处理请求的逻辑...
}
// Context 结构体
type Context struct {
// 其他字段...
}
// reset 重置 Context 对象的状态
func (c *Context) reset() {
// 重置 Context 对象的状态...
}
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)