Gone框架介绍30 - 使用`goner/gin`提供Web服务

2024-06-23 07:36

本文主要是介绍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.Controllergoner/gin启动过程中会自动调用Mount()方法;我们需要再该方法中挂载我们希望处理的路由。

为此,我们需要在controller上添加一个gone.RouteGroup类型的root字段,使用gone:"*"标记为依赖注入;Gone会将代表根路由的gone.RouteGroup装配到root属性上。gone.RouteGroup是一个接口,定义了用于挂载路由的GETPOST等方法,下面是其定义:

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定义可以看到,GETPOST等用于挂载路由的函数,都可以接收多个HandlerFunc参数。HandlerFunc要求是一个函数,这里称为路由处理函数

路由处理函数,可以接收多个参数,也可以返回多个值;一般返回两个值,一个正常值 和 一个 error 值,如下:

func processRoute(ctx *gin.Context) (string, error) {return "hello gone", nil
}

正常值的类型可以为 golang 的简单类型(int、string、float 等)、结构体、指针、接口、数组、slice、map 等;还可以返回 io.Readerchan 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请求参数注入

路由处理函数的参数,支持依赖注入。

  1. 支持注册到Gone的Goners类型直接作为参数,例如以gone.Logger类型作为参数:
	ctr.root.GET("inject", func(logger gone.Logger) string {logger.Infof("inject")return "inject"})
  1. 支持以*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"})
  1. 支持参数为一个匿名结构体,在结构体上做依赖注入标记:
	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监听端口int8080
server.host监听地址string0.0.0.0
server.modegin mode,可选值为:debug、test、releasestringrelease
server.html-tpl-pattern用于gin.LoadHTMLGlob加载模版路径string<空>
server.health-check配置一个路径用于监控检查string<空>
server.log.show-access-log是否打印访问日志booltrue
server.log.show-request-time是否在日志中打印请求耗时booltrue
server.log.data-max-length日志数据最大长度,超过该长度会截断,0为不限制int0
server.proxy.stat代理耗时统计boolfalse
server.return.wrapped-data使用{"code": ${code}, "msg": ${msg}, "data": ${data} }封装数据booltrue

更多例子

跳转 快速开始

这篇关于Gone框架介绍30 - 使用`goner/gin`提供Web服务的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1086535

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他