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

2021年9月24日 11点热度 0条评论 来源: 飞翔的风筝

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/app/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

嗯,真的结束了!

    原文作者:飞翔的风筝
    原文地址: https://www.cnblogs.com/lpit/p/15325675.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。