golang gin框架入门教程

1. golang gin框架介绍

Gin 是 Go语言写的一个 web 框架,它具有运行速度快,分组的路由器,良好的崩溃捕获和错误处理,非常好的支持中间件和 json。总之在 Go语言开发领域是一款值得好好研究的 Web 框架,开源网址:https://github.com/gin-gonic/gin

2. golang gin框架安装

安装 (go version 1.13+ is required):
go get -u github.com/gin-gonic/gin

3. 如何使用gin开始一个Http Server

创建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方法。

4. 常见项目结构

接下来就开始创建项目来学习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等。

5. gin的路由

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 /中国%

6. gin获取请求参数和响应请求

6.1 query string参数与body参数

web提供的服务通常是client和server的交互。其中客户端向服务器发送请求,除了路由参数,其他的参数无非两种,查询字符串query string和报文体body参数。所谓query string,即路由用,用?以后连接的key1=value2&key2=value2的形式的参数。当然这个key-value是经过urlencode编码。

6.2 query string

对于参数的处理,经常会出现参数不存在的情况,对于是否提供默认值,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不存在的时候,提供默认值。

6.3 body

http的报文体传输数据就比query string稍微复杂一点,常见的格式就有四种。例如application/jsonapplication/x-www-form-urlencoded, application/xmlmultipart/form-data。后面一个主要用于图片上传。json格式的很好理解,urlencode其实也不难,无非就是把query string的内容,放到了body体里,同样也需要urlencode。默认情况下,c.PostFROM解析的是x-www-form-urlencodedfrom-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

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

评论

皖ICP备2023023451号

Copyright © L1MN.COM 联系方式:l1mnfw@163.com