您的位置:首页 > 编程语言 > Go语言

Go学习【02】:理解Gin,搭一个web demo

2021-09-23 19:45 1046 查看

Go Gin 框架

说Gin是一个框架,不如说Gin是一个类库或者工具库,其包含了可以组成框架的组件。这样会更好理解一点。

举个🌰

下面的示例代码在这:github https://github.com/lpgyouxi/gogo
利用Gin组成最基本的框架。说到框架,我们可以先列举下需要的(最基本)组件,主要四块,以及下面的重点。

  • 端口监听 用于监听请求,也就是服务
  • 请求处理
      请求分发
    • 结果处理
  • 路由
      路由编写
    • 路由接入
  • 业务处理
      写一个demo

    好,开搞!

    前提
    * 你已经安装好go环境,没安装的可以百度下,教程很多
    * 你已经安装了Gin,如果没安装,安装命令:go get -u github.com/gin-gonic/gin
    // Github上有https://github.com/gin-gonic/gin,大牛直接看这个不用看下面的了
    * 建一个项目文件夹 gogo
    * 初始化环境go  mod init 模块名或者项目名
    // 比如我把这个测试项目取名为 gogo ; go  mod init gogo

    端口监听

    端口监听: 主要是监听端口的消息,提供服务入口。

    文件位置:~/gogo/server.go

    package main
    import (
    "github.com/gin-gonic/gin"
    "net/http"
    )
    
    func main()  {
    server := gin.Default()
    server.GET("/", func(c *gin.Context) {
    param := c.DefaultQuery("name", "Guest")  //注意:gin.Context 、参数获取
    c.JSON(http.StatusOK, gin.H{
    "message": "hello 测试通过",
    "data":param,
    })
    })
    server.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
    }
    
    ---------------------------
    // 注意上面标识“注意”的行,后面可能会用到
    // http://127.0.0.1:8080/?name=123456789
    {
    data: "123456789",
    message: "hello 测试通过"
    }

    为了框架的整体连贯性,后面会对其优化。

    请求处理

    请求与返回可以看成业务处理的前置和后置部分,一般分为两部分request和response,即 请求处理和返回处理,如下:

    从这里我将代码统一放到web的app目录下,具体路径如下

    请求处理

    ~/gogo/app/distribute/request.go

    package distribute
    
    import (
    "github.com/gin-gonic/gin"
    )
    
    /**
    分配:链接上下文
    link context
    */
    
    // 定义一个接受参数的函数类型
    type AppReqestFunc func(*AppReqest)
    
    //定义参数结构体
    type AppReqest struct {
    *gin.Context
    }
    
    /*
    定义参数赋予方法
    */
    func Handle(r AppReqestFunc) gin.HandlerFunc {
    // gin.HandlerFunc 理解为一种可操作的函数接口,匿名函数
    return func(c *gin.Context) {
    r(&AppReqest{c})
    }
    }
    
    /*
    定义参数获取法
    */
    
    //定义获取get参数
    func (params AppReqest) InputGet(paramName string) string {
    return params.DefaultQuery(paramName, "")
    }
    
    /*
    定义返回方法
    */
    
    //成功返回
    func (c *AppReqest) Success(data interface{}) {
    c.JSON(Success(data))
    }

    Handle
    定义了需要接受一个函数类型
    AppReqestFunc func(*AppReqest)
    ,其中参数满足
    AppReqest

    会返回一个

    gin.HandlerFunc
    类型,这个类型适用于Gin的路由参数类型(即gin可调用)。

    这里

    Handle
    可以做一些自定义的扩展。

    返回处理

    ~/gogo/ap 15b0 p/distribute/response.go

    package distribute
    
    import (
    "github.com/gin-gonic/gin"
    "net/http"
    "reflect"  // 对象操作的类
    )
    
    /**
    成功返回,你可以建其它返回,如失败、错误
    Successful return, you can create other returns, such as failure and error
    */
    func Success(data interface{}) (int, gin.H) {
    ref := reflect.ValueOf(data)
    if ref.IsNil() {
    return http.StatusOK, gin.H{
    "code":    http.StatusOK,
    "data":    make(map[string]interface{}),
    "message": "请求成功",
    }
    } else {
    return http.StatusOK, gin.H{
    "code":    http.StatusOK,
    "data":    data,
    "message": "请求成功",
    }
    }
    }

    一个返回格式,大致了解就行,可以自行丰富。

    总结:上面两个文件分别是如何接受请求头,和返回的格式,注意下

    参数赋予方法
    这个可能不好理解,可以在纸上面画画,方便理解。

    路由

    路由编写

    为了以后的路由扩展,将server中的路由单独存放,代码如下:

    ~/gogo/app/routes/api.go

    package routes
    
    import (
    "github.com/gin-gonic/gin"
    //  "gogo/app/http"    //业务模块
    "gogo/app/distribute"
    )
    
    func Route(e *gin.Engine) {
    
    //test
    e.GET("/", func(c *gin.Context) {
    c.JSON(200, gin.H{
    "message": "hello",
    })
    })
    // 业务
    // test := http.TestController{}
    // e.GET("/test", distribute.Handle(test.Test))
    // e.GET("/hello", distribute.Handle(test.Hello))
    }

    路由还可以分组,分文件,这里就不过多描述了,可以自己想想怎么扩展。

    上面的

    e.GET
    可以按自己的需求进行编写,这里是举了个🌰

    路由接入

    为了将路由使用到项目中,需要一个中间衔接的文件,实现方式为添加一个启动文件,将启动服务时需要加载的文件或功能加载进来。

    ~/gogo/app/boot/bootstrap.go

    package boot
    
    import (
    "github.com/gin-gonic/gin"
    "gogo/app/routes"
    )
    
    // 启动入口
    func Bootstrap(c *gin.Engine) {
    SetRoute(c)
    }
    
    // 路由入口
    func SetRoute(c *gin.Engine) {
    routes.Route(c)
    }

    这里将上面路由文件加载进来了,现在改造服务文件,加这个文件加载进去。

    package main
    import (
    "github.com/gin-gonic/gin"
    // "net/http"
    "gogo/app/boot"
    )
    
    func main()  {
    server := gin.Default()
    
    boot.Bootstrap(server)
    // server.GET("/", func(c *gin.Context) {
    // 	param := c.DefaultQuery("name", "Guest")
    // 	c.JSON(http.StatusOK, gin.H{
    // 		"message": "hello 测试通过",
    // 		"data":param,
    // 	})
    // })
    
    server.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
    }

    和最前面的对比,可以看见,将路由替换为了:

    boot.Bootstrap(server)
    ,进行加载路由文件。

    业务处理

    一个业务demo

    注意前面路由文件,有个路由如下

    // 业务
    // test := http.TestController{}
    // e.GET("/test", distribute.Handle(test.Test))
    // e.GET("/hello", distribute.Handle(test.Hello))

    将其全部打开;同时可以看到头部的引入:

    "gogo/app/http"
    ;所以下面看看业务文件怎么编写:

    ~/gogo/app/http/test.go

    package httpimport (	"github.com/gin-gonic/gin"	"gogo/app/distribute"	"fmt")type TestController  struct {}func (r *TestController) Hello(request *distribute.AppReqest) {	fmt.Println("Ok");	request.Success(make([]int, 0));}func (r *TestController) Test(request *distribute.AppReqest) {		request.JSON(200, gin.H{			"message": "hello 测试通过",		})}

    上面的Hello和Test就是业务代码块,展示了返回的方式

    success
    即是上面说到的返回处理。如果是复杂逻辑可以将详细的业务代码引入到这里,就不赘述了。

    测试例子

    http://127.0.0.1:8080/hello
    -----------------------------------
    {
    code: 200,
    data: [ ],
    message: "请求成功"
    }

    新增方法

    例子:

    gogo/app/routes/api.go增加路由

    // exp: get 、 param
    e.GET("/get", distribute.Handle(test.TestGet))

    gogo/app/http/test.go增加业务代码

    func (r *TestController) TestGet(request *distribute.AppReqest) {
    var data = []string{}
    var name = request.InputGet("name")
    data = append(data,name)
    request.Success(data);
    }

    请求

    http://127.0.0.1:8080/get?name=Lucy
    -----------------------------------
    {
    code: 200,
    data: [
    "Lucy"
    ],
    message: "请求成功"
    }

    至此,一个微型的例子就完成了。目录结构如下:

    |____go.mod
    |____server.go
    |____app
    | |____boot
    | | |____bootstrap.go
    | |____distribute
    | | |____response.go
    | | |____request.go
    | |____http
    | | |____test.go
    | |____routes
    | | |____api.go
    |____LICENSE
    |____go.sum
    |____README.md

    结束

    基础的学习go web,深入的话还是需要实践。 上面的代码在这:github

    嗯,真的结束了!

  • 内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: