Go Gin 框架
说Gin是一个框架,不如说Gin是一个类库或者工具库,其包含了可以组成框架的组件。这样会更好理解一点。
举个
下面的示例代码在这:github
利用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
嗯,真的结束了!