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服务
gone是可以高效开发Web服务的Golang依赖注入框架 github地址:https://github.com/gone-io/gone 文档地址:https://goner.fun/zh/ 使用goner/gin提供Web服务 文章目录 使用goner/gin提供Web服务注册相关的Goners编写Controller挂载路由路由处理函数io.Rea…...
Lipowerline5.0 雷达电力应用软件下载使用
1.配网数据处理分析 针对配网线路点云数据,优化了分类算法,支持杆塔、导线、交跨线、建筑物、地面点和其他线路的自动分类;一键生成危险点报告和交跨报告;还能生成点云数据采集航线和自主巡检航线。 获取软件安装包联系邮箱:289…...
STM32学习之一:什么是STM32
目录 1.什么是STM32 2.STM32命名规则 3.STM32外设资源 4. STM32的系统架构 5. 从0到1搭建一个STM32工程 学习stm32已经很久了,因为种种原因,也有很久一段时间没接触过stm32了。等我捡起来的时候,发现很多都已经忘记了,重新捡…...
AI绘画Stable Diffusion 超强一键去除图片中的物体,免费使用!
大家好,我是设计师阿威 在生成图像时总有一些不完美的小瑕疵,比如多余的物体或碍眼的水印,它们破坏了图片的美感。但别担心,今天我们将介绍一款神奇的工具——sd-webui-cleaner,它可以帮助我们使用Stable Diffusion轻…...
零基础STM32单片机编程入门(一)初识STM32单片机
文章目录 一.概要二.单片机型号命名规则三.STM32F103系统架构四.STM32F103C8T6单片机启动流程五.STM32F103C8T6单片机主要外设资源六.编程过程中芯片数据手册的作用1.单片机外设资源情况2.STM32单片机内部框图3.STM32单片机管脚图4.STM32单片机每个管脚可配功能5.单片机功耗数据…...
Github上前十大开源Rust项目
在github上排名前十的Rust开源项目整理出来与大家共享,以当前的Star数为准。 Deno Deno 是 V8 上的安全 TypeScript 运行时。Deno 是一个建立在V8、Rust和Tokio之上的 JavaScript、TypeScript 和 WebAssembly 的运行时环境,具有自带安全的设置和出色的开…...
硬件开发笔记(二十):AD21导入外部下载的元器件原理图库、封装库和3D模型
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/139707771 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…...
竞赛选题 python opencv 深度学习 指纹识别算法实现
1 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 python opencv 深度学习 指纹识别算法实现 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:4分创新点:4分 该项目较为新颖…...
RK3568开发笔记(三):瑞芯微RK3588芯片介绍,入手开发板的核心板介绍
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/139905873 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…...
EtherCAT主站IgH解析(二)-- 如何将Igh移植到Linux/Windows/RTOS等多操作系统
版权声明:本文为本文为博主原创文章,转载请注明出处 https://www.cnblogs.com/wsg1100 如有错误,欢迎指正。 本文简单介绍如何将 igh 移植到 zephyr、freertos、rtems、rtthread等RTOS ,甚至 windows 上。 ##前言 目前࿰…...
ansible copy模块参选选项
copy模块用于将文件从ansible控制节点(管理主机)或者远程主机复制到远程主机上。其操作类似于scp(secure copy protocol)。 关键参数标红。 参数: src:(source:源) 要复制到远程…...
展厅设计主要的六大要素
1、从创意开始 展示设计的开始必须创意在先。根据整体的风格思路进行创意,首先要考虑的是主体的造型、大小高度位置以及它和周围展厅的关系。另外其他道具设计制作与运作方式也必须在创意中有明确的体现。 2、平面感 平面感是指对展示艺术设计平面图纸审美和功能两个…...
【数据结构与算法】最小生成树,Prim算法,Kruskal算法 详解
最小生成树的实际应用背景。 最节省经费的前提下,在n个城市之间建立通信联络网。 Kruskal算法(基于并查集) void init() {for (int i 1; i < n; i) {pre[i] i;} }ll root(ll a) {ll i a;while (pre[i] ! i) {i pre[i];}return i p…...
【启明智显产品分享】Model3工业级HMI芯片详解系列专题(三):安全、稳定、高防护
芯片作为电子设备的核心部件,,根据不同的应用领域被分为不同等级。工业级芯片适用于工业自动化、控制系统和仪器仪表等领域,对芯片的安全、稳定、防护能力等等有着较高的要求。这些芯片往往需要具备更宽的工业温度范围,能够在更恶…...
【面试干货】Java中的四种引用类型:强引用、软引用、弱引用和虚引用
【面试干货】Java中的四种引用类型:强引用、软引用、弱引用和虚引用 1、强引用(Strong Reference)2、软引用(Soft Reference)3、弱引用(Weak Reference)4、虚引用(Phantom Reference…...
对称/非对称加密
对称加密和非对称加密是两种主要的加密方式,用于保护数据的机密性和完整性。它们在密钥的使用和管理上有着显著的不同。 对称加密 原理 对称加密(Symmetric Encryption)使用相同的密钥进行加密和解密。这意味着发送方和接收方必须共享相同…...
DDei在线设计器-API-DDeiSheet
DDeiSheet DDeiSheet是代表一个页签,一个页签含有一个DDeiStage用于显示图形。 DDeiSheet实例包含了一个页签的所有数据,在获取后可以通过它访问其他内容。DDeiFile中的sheets属性记录了当前文件的页签列表。 一个DDeiFile实例至少包含一个DDeiSheet…...
随想录 Day 69 并查集 107. 寻找存在的路径
随想录 Day 69 并查集 107. 寻找存在的路径 理论基础 int n 1005; // n根据题目中节点数量而定,一般比节点数量大一点就好 vector<int> father vector<int> (n, 0); // C里的一种数组结构// 并查集初始化 void init() {for (int i 0; i < n; i)…...
Hi3861 OpenHarmony嵌入式应用入门--LiteOS Mutex
CMSIS 2.0接口中的Mutex(互斥锁)是用于在多线程环境中保护共享资源的访问机制。Mutex(互斥锁)是一种特殊的信号量,用于确保同一时间只有一个线程可以访问特定的共享资源。 在嵌入式系统或多线程应用中,当多…...
使用STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集
文章目录 一、什么是“软件I2C”和“硬件I2C”1.1 什么是“软件I2C”1.2 什么是“硬件I2C” 二、软件I2C和硬件I2C2.1 软件模拟2.2硬件I2C 三、配置STM32CubeMX四、配置keil代码4.1 创建文件4.2 复制文件4.3 在keil中添加文件4.4 添加路径4.5 代码修改 五、硬件连接六、总结 一…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
