本文主要是介绍Gone框架介绍30 - 使用`goner/gin`提供Web服务,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
gone是可以高效开发Web服务的Golang依赖注入框架
github地址:https://github.com/gone-io/gone
文档地址:https://goner.fun/zh/
使用goner/gin
提供Web服务
文章目录
- 使用`goner/gin`提供Web服务
- 注册相关的Goners
- 编写Controller挂载路由
- 路由处理函数
- io.Reader
- chan any
- HTTP请求参数注入
- 配置项
- 例子,将端口改为 `8000`
- 更多配置项
- 更多例子
注册相关的Goners
这里我们编写一个Priest
函数,用于注册相关的Goners。
package main
import ("github.com/gone-io/gone""github.com/gone-io/gone/goner"
)// 用于注册Goners的Priest函数
func Priest(cemetery gone.Cemetery) error {//注册gin相关的Goners_ = goner.GinPriest(cemetery)//TODO: 注册其他的Gonersreturn nil
}func main() {// 在main函数中使用Priest函数启动服务gone.Serve(Priest)
}
将上面代码保存为main.go
,,代码已经能够正常运行起来了,运行中代码会监听本地8080
端口,但是所有的请求都是返回404。
编写Controller挂载路由
为了提供服务,而不只是返回404,我们需要编写一个Controller,挂载路由。
新建文件controller.go
,编写如下代码:
// NewController controller 的构造函数
func NewController() gone.Goner {return &controller{}
}type controller struct {gone.Flagroot gone.RouteGroup `gone:"*"` // 根路由组
}func (ctr *controller) Mount() gone.GinMountError {ctr.root.GET("/ping", func() string {return "hello gone"})return nil
}
然后,在main.go
文件Priest
函数中添加注册Controller
的代码:
//注册Controllercemetery.Bury(NewController())
再次运行代码:go run .
,使用curl
命令访问localhost:8080/ping
,返回{"code":0,"data":"hello gone"}
。
上面代码中,controller
通过实现方法Mount() gone.GinMountError
成为gin.Controller
,goner/gin
启动过程中会自动调用Mount()
方法;我们需要再该方法中挂载我们希望处理的路由。
为此,我们需要在controller
上添加一个gone.RouteGroup
类型的root
字段,使用gone:"*"
标记为依赖注入;Gone会将代表根路由的gone.RouteGroup
装配到root属性上。gone.RouteGroup
是一个接口,定义了用于挂载路由的GET
、POST
等方法,下面是其定义:
type IRoutes interface {Use(...HandlerFunc) IRoutesHandle(string, string, ...HandlerFunc) IRoutesAny(string, ...HandlerFunc) IRoutesGET(string, ...HandlerFunc) IRoutesPOST(string, ...HandlerFunc) IRoutesDELETE(string, ...HandlerFunc) IRoutesPATCH(string, ...HandlerFunc) IRoutesPUT(string, ...HandlerFunc) IRoutesOPTIONS(string, ...HandlerFunc) IRoutesHEAD(string, ...HandlerFunc) IRoutes
}type IRouter interface {IRoutesGetGinRouter() gin.IRouterGroup(string, ...HandlerFunc) RouteGroupLoadHTMLGlob(pattern string)
}// RouteGroup route group, which is a wrapper of gin.RouterGroup, and can be injected for mount router.
type RouteGroup interface {IRouter
}
路由处理函数
通过RouteGroup
定义可以看到,GET
、POST
等用于挂载路由的函数,都可以接收多个HandlerFunc
参数。HandlerFunc要求是一个函数,这里称为路由处理函数。
路由处理函数,可以接收多个参数,也可以返回多个值;一般返回两个值,一个正常值 和 一个 error 值,如下:
func processRoute(ctx *gin.Context) (string, error) {return "hello gone", nil
}
正常值的类型可以为 golang 的简单类型(int、string、float 等)、结构体、指针、接口、数组、slice、map 等;还可以返回 io.Reader
和 chan any
两种特殊类型。
io.Reader
通过io.Reader可以返回任意的数据,比如返回一个文件:
ctr.root.GET("/file", func() (io.Reader, error) {return os.Open("main.go")})
重启后,用curl测试:curl -o main.go http://localhost:8080/file
,可以下载到main.go文件。
特别提醒一下,将http://localhost:8080/file
输入到浏览器地址栏并不会触发下载,而是直接显示了文件内容,这是因为返回的是文本内容,并且又缺少触发下载的Header:Content-Disposition
。
chan any
通过返回chan any,可以方便的实现一个SSE服务。
type Info struct {Msg string `json:"msg"`Index int `json:"index"`}ctr.root.GET("/sse", func() chan any {ch := make(chan any)go func() {defer close(ch) //注意关闭channelfor i := 0; i < 3; i++ {time.Sleep(time.Second)ch <- Info{Index: i,Msg: "hello gone",}}}()return ch})
在Mount
函数中添加上面代码,然后重启服务。使用curl测试:curl http://localhost:8080/sse
,可以得到如下输出(每秒收到一个event):
event: data
data: {"msg":"hello gone","index":0}event: data
data: {"msg":"hello gone","index":1}event: data
data: {"msg":"hello gone","index":2}event: done
HTTP请求参数注入
路由处理函数的参数,支持依赖注入。
- 支持注册到Gone的Goners类型直接作为参数,例如以
gone.Logger
类型作为参数:
ctr.root.GET("inject", func(logger gone.Logger) string {logger.Infof("inject")return "inject"})
- 支持以
*gin.Context
、*gone.Context
类型作为参数:
gone.Context
是对gin.Context
的封装,兼容gin.Context
。
ctr.root.GET("inject", func(logger gone.Logger, ctx *gone.Context) string {logger.Infof("inject")logger.Infof("hots: %s", ctx.Request.Host)return "inject"})
- 支持参数为一个匿名结构体,在结构体上做依赖注入标记:
ctr.root.GET("inject", func(logger gone.Logger, ctx gone.Context, in struct {selects []int `gone:"http,query=select"` //HTTP参数注入:表示取query参数中的select作为数组,要求值可以转为int类型logger2 gone.Logger `gone:"*"` //注入gone.Logger类型的logger}) string {logger.Infof("inject")logger.Infof("hots: %s", ctx.Request.Host)logger.Infof("selects: %v", in.selects)return "inject"})
更多关于 HTTP请求参数注入 只是,请参考:HTTP 注入说明
配置项
goner/gin
支持通过配置,改变默认行为;关于配置的读取和配置文件的格式参考 配置读取
例子,将端口改为 8000
创建配置文件:
mkdir config
echo 'server.port=8000' > config/default.properties
更多配置项
配置项 | 说明 | 类型 | 默认值 |
---|---|---|---|
server.port | 监听端口 | int | 8080 |
server.host | 监听地址 | string | 0.0.0.0 |
server.mode | gin mode,可选值为:debug、test、release | string | release |
server.html-tpl-pattern | 用于gin.LoadHTMLGlob加载模版路径 | string | <空> |
server.health-check | 配置一个路径用于监控检查 | string | <空> |
server.log.show-access-log | 是否打印访问日志 | bool | true |
server.log.show-request-time | 是否在日志中打印请求耗时 | bool | true |
server.log.data-max-length | 日志数据最大长度,超过该长度会截断,0为不限制 | int | 0 |
server.proxy.stat | 代理耗时统计 | bool | false |
server.return.wrapped-data | 使用{"code": ${code}, "msg": ${msg}, "data": ${data} } 封装数据 | bool | true |
更多例子
跳转 快速开始
这篇关于Gone框架介绍30 - 使用`goner/gin`提供Web服务的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!