gin-巧用Context传递多种参数

2023-11-10

目录

 

引言:

1.巧妙包装gin.Context为NewContext

2 在使用gin.Use对每一个请求的Context进行组装

3 在路由绑定时解析出NewContext来为应用层函数提供参数,并且调用应用层函数

4 总结


引言:

首先给臆造这样一个场景:

假设有web端,有众多用户需要从服务端去索取数据。

分析下这个过程,由于web端有大量用户去访问,每个用户请求的数据是不同的(假设数据库中的数据已经用用户的唯一id进行了区分),那么web端的每次请求中,都应该携带登录用户的id信息。

因此服务端要做的就是根据网络请求中的id及其他信息去数据库中找到匹配的信息并返回。

1.巧妙包装gin.Context为NewContext

熟悉的gin.HandlerFunc的参数为 *gin,Context,因此为了能传递更多的参数,可以设计如下图的这样一种新的结构。

上面这种结构可以作为应用层函数的一个参数,并可以通过应用层一直传递到数据层。那么,如何将NewContext和gin.Context结合起来的,看下一步。

2 在使用gin.Use对每一个请求的Context进行组装

gin提供了gin.Use方法来对每个请求进行相应的处理,因此为了能将gin.Context将NewContext组装在一起,我们可以编写如下函数:

//gin.Use接收的参数为gin.Handlerfunc
func InitContext()gin.HandlerFunc{
	return func(c *gin.Context) {
		bc := new(NewContext)
        bc.ID = c.GetHeader("ID") //从网络请求中拿出id
		bc.DBClient = base.Client //这里为数据库连接,可以为新申请的,也可以为全局的,我这里是全局的
		c.Set("context",bc)//将NewContext加入在gin.Context中
	}
}

在InitContext中,已经将NewContext初始化,并且通过set方法加入到了gin.Context之中,通过下面代码,每一条网络请求的路由的Context中都会持NewContext。

router := gin.New()
router.Use(InitContext)

通过上面的操作,在后续的路由绑定中,我们只需要解析出NewContext来进行应用层函数的调用,这样NewContext的内容就可以一直传递,直到gin.Context cancel掉。

下面将展示如何在路由绑定中将NewContext拿出,并且能在整个gin.Context声明周期中存活。

3 在路由绑定时解析出NewContext来为应用层函数提供参数,并且调用应用层函数

在路由绑定中,我们使用的其都是如下所示的操作:

group := GroupRouter{router.Group("/api/v1")}//路由组
	//WeChatEventsAPIs(API_V1)
group.POST(请求路径 string ,响应函数 gin.HandlerFunc)   //路由绑定

其中group为路由组,而在路由绑定中,响应函数为gin.HandlerFunc形式,如下:

type HandlerFunc func(*gin.Context)

因此我们在这里可以这样做,编写函数Convert,此函数接收参数为应用层的函数(应用层函数的参数类型可以设置为NewContext),在Convert函数中返回gin.HanderFunc类型的函数,并且在gin.handlerFunc类型的函数中来对应用层的方法进行调用(文字难以表示清楚,详见代码)

详细如下:

//这里 Convert的参数为NewContext的成员方法的类型,Convert的返回值为gin中的响应函数的类型
func Convert(hd HandlerFunc) gin.HandlerFunc {
	return func(c *gin.Context) {
		context,exi := ctx.Get("context")
	    if exi==false{//不存在
            c.JSON(http.StatusBAD)//返回给web错误
        }
		json := hd(context) //调用应用层方法,冰鞋得到返回值,应用层后续可以调用业务层等等
		c.JSON(http.StatusOK,json)
	}
}

因此,路由绑定时应该都是如下格式的:

group.POST(请求路径 string ,Convert(应用层方法))  

这样,我们就可以从应用层往下传递NewContext中的所有信息,在实际项目中,我们要传递的信息很多,都可以通过再NewContext中来组装,并且通过上述方式来进行参数的传递。

4 总结

相比较于传统的每次在gin.Context中通过set方法来设置参数,这种NewContext和gin.Context结合的方法更为简洁,在应用层只需要关注NewContext参数,即只需要关注我们需要的参数,我不需要将整个gin.Context都拿出来,大大提高了代码的执行效率和阅读性。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

gin-巧用Context传递多种参数 的相关文章

  • 为什么 golang 堆配置文件中的“Total MB”小于顶部的“RES”?

    我有一个用 go 编写的服务 在运行时需要 6 7G 内存 RES 在顶部 所以我使用 pprof 工具试图找出问题所在 go tool pprof pdf http
  • 如何在Go中从interface{}解组到interface{}

    我的系统中有多个通过 RPC 进行通信的节点 我正在尝试通过 RPC 将 map string interface 发送到另一个节点 发送方使用 json Marshal 接收方使用 json Unmarshal 来获取地图 假设在发送方
  • gcloud 部署应用程序找不到导入包 - golang

    我已经将应用程序的一个版本部署到 GAE 但现在部署新版本时遇到问题 当我尝试时gcloud app deploy version VERSION 我收到一堆错误 显示远程构建找不到我的导入包 Beginning deployment of
  • Golang 中的“相互”包导入

    是否可以在 Golang 中执行 相互 包导入之类的操作 举例来说 我有两个包 A 和 B 分别具有 AFunc 和 BFunc BFunc2 函数 package A import B func AFunc do stuff but al
  • 如何检查我的 golang 应用程序是否使用 Boringcrypto 而不是本机 golang crypto?

    上下文 我正在阅读多篇有关使我的 golang 应用程序符合 FIPS 要求的文章 换句话说 使我的应用程序使用 Boringcrypto 而不是本机 golang crypto https kupczynski info posts fi
  • 将具有联合字段的 C 结构映射到 Go 结构

    我从 Go 中的某些 WinApi 的系统调用中获取结果 我可以轻松地从 C 代码映射简单的结构 但是如何处理如下所示的 C 结构 typedef struct SPC LINK DWORD dwLinkChoice define SPC
  • Golang delve,如何启动调试器并启动正在调试的应用程序?

    我正在尝试设置一个可以远程连接的无头深度调试器 我无法找到一种方法来启动调试服务器 而该服务器不会暂停我正在调试的应用程序 我一直在使用dlv attach headless true listen 2345 attach 32但这会暂停该
  • 使用 Golang 通道处理 HTTP 请求

    我正在尝试构建一个简单的 Golang Appengine 应用程序 它使用通道来处理每个 http 请求 原因是我希望每个请求执行合理的大型内存计算 并且每个请求都以线程安全的方式执行 即来自并发请求的计算不会混合 这一点很重要 本质上
  • 带 cookie 身份验证的 Gorilla websocket

    这是我的设置 我正在构建一个带有用户登录的服务 使用 Negroni 和 Gorilla 登录后 用户会获得一个会话 cookie 服务器使用该会话 cookie 来授权受保护的端点 受保护的端点之一允许用户 客户端与服务器打开 Webso
  • Cgo 生成的源无法在 MVC 上编译

    我有一个用 CGo 制作的共享库 它在 Linux 和 Android 上链接得很好 但是 当使用 Microsoft Visual Studio 2017 在 Windows 10 上进行编译时 出现以下错误 Microsoft R Pr
  • 使用 MongoDB Atlas 时 mongo-go-driver 因服务器选择超时而失败

    去版本 1 12 5 我有这个使用 node js mongo 驱动程序的代码 const MongoClient require mongodb MongoClient const uri process env MONGO HOST d
  • 在 Alpine 中找不到运行时/cgo

    In an alpine edge我安装的容器通过 RUN apk add no cache musl dev go 我试着跑go get github com golang protobuf protoc gen go then 这会导致
  • 如何通过模板中的变量访问对象字段?

    我有一个嵌套循环 columns columns range dx dataList range c columns index dx c end end dataList是orm模型数组 和ID Title字段 那么columns is
  • 在 Go 中执行字节数组

    我正在尝试在 Go 程序中执行 shellcode 类似于使用其他语言执行此操作的方式 示例 1 C 程序中的 Shellcode https stackoverflow com questions 16626857 shellcode i
  • 我想在后端验证来自 golang 前端的时区

    前端在注册期间发送时区以及其他用户详细信息 我需要在时区上放置一个验证器来进行 api 测试 时区数据的格式为 GMT 10 00 Hawaii GMT 08 00 Pacific Time US amp Canada 我所做的是定义数组中
  • 从 []byte 到 char*

    我想包装一个 C 函数 它需要一个char 指向非空字节缓冲区 的第一个元素 我正在尝试使用 CGo 将其包装在 Go 函数中 以便我可以将其传递给 byte 但我不知道如何进行转换 C 函数签名的简化版本是 void foo char c
  • 构建链代码时 ltdl.h 未找到错误

    我正在尝试使用构建链码go build 当我运行 Go build 命令时它的报告 hyperledger fabric vendor github com miekg pkcs11 pkcs11 g o 29 18 fatal error
  • 为什么奇数的切片容量与偶数的切片行为不同

    我注意到 当容量为奇数时 切片的容量会以不同的方式表现 更具体地说 当向切片添加元素时 切片的容量为doubled当原始容量为偶数时 但当原容量为奇数时 容量为增加一 然后加倍 例子 s make int 28 28 s append s
  • 是否可以获取有关 Golang 中调用者函数的信息?

    是否可以获取有关 Golang 中调用者函数的信息 例如 如果我有 func foo Do something func main foo 我怎样才能得到那个foo已被呼叫来自main 我可以用其他语言实现这一点 例如在 C 中我只需要使用
  • 匿名结构和空结构

    http play golang org p vhaKi5uVmm http play golang org p vhaKi5uVmm package main import fmt var battle make chan string

随机推荐

  • map erase 内存释放问题

    资料出处 http www cnblogs com goodness archive 2012 05 16 2503832 html 研究了下c 中map的内存占用情况 很多人说map中的erase以及clear不能释放内存 这几天实验了下
  • 多态介绍。

    Override 规范上 推荐加上 帮你校验是否是方法重写 方法重写在子类继承了父类的方法之后 如果发现在当前的需求下 父类的方法不够强大 所以在子类中就可以对此方法进行重写 特点 1 方法名相同 2 参数列表相同 3 返回值类型不能大于父
  • Python绘制时间序列数据的时序图、自相关图和偏自相关图

    时序图 自相关图和偏相关图是判断时间序列数据是否平稳的重要依据 本文涉及的扩展库numpy pandas statsmodels一般可以使用pip进行在线安装 如果安装失败 可以到http www lfd uci edu gohlke py
  • [Luogu] P1438 无聊的数列

    题目背景 无聊的 YYB 总喜欢搞出一些正常人无法搞出的东西 有一天 无聊的 YYB 想出了一道无聊的题 无聊的数列 K峰 这题不是傻X题吗 题目描述 维护一个数列 a i a i ai 支持两种操作 1 l r K D 给出一个长度等于
  • java 接口类与抽象类

    接口可以继承接口 抽象类可以实现 implements 接口 但不可以继承自接口 抽象类可以继承具体类 抽象类中可以有静态的 main 方法 抽象类里可以有抽象方法 抽象方法一定要在抽象类里 抽象类可以派生 抽象类的父类可以是非抽象类 某一
  • XSS之xss-labs-level5

    文章目录 0x01 XSS Labs 0x02 实验工具 0x03 实验环境 0x04 实验步骤 0x05 实验分析 0x06 参考链接 0x01 XSS Labs XSS 跨站脚本攻击 是指恶意攻击者往Web页面里插入恶意Script代码
  • 递归对比对象函数

    在JavaScript中 对象之间的比较通常通过引用进行 当你使用 运算符比较两个对象时 它会检查它们是否引用了同一个内存地址 而不是逐个比较对象的属性 上图可见 obj1和 是两个不同的对象 尽管它们具有相同的结构 都是空对象 因此 使用
  • vue项目使用vue-video-player实现视频直播功能

    文章目录 引言 一 基本使用 1 播放mp4 2 options常用属性 3 常用事件 二 使用videojs contrib hls播放m3u8 三 视频链接测试工具 potplayer 引言 随着互联网的快速发展 视频直播已经成为了越来
  • [C++]拷贝(复制)构造函数

    拷贝 复制 构造函数 拷贝构造函数是一种特殊的构造函数 其形参为本类的对象引用 形式如下 class 类名 public 类名 形参 构造函数 类名 类名 对象名 拷贝构造函数 拷贝构造函数实例 include
  • C语言程序设计--学生信息管理系统

    题目 学生信息管理系统 1 系统设计 1 1设计要求 1 1 1设计任务 创建一个学生信息管理系统 让它来运行和管理学生信息 进行对学生学号 姓名 性别 年龄 出生年月日 住址 电话 E maill等信息的管理 1 1 2性能指标要求 程序
  • 刷脸支付随刷随走用户体验更好

    目前不管是商铺还是银行 又或者是交通等领域都已实现刷脸支付应用 我们的社会已经初步进入了靠脸吃饭的时代 相信很多用户都很是好奇 扫码支付才盛行不久 而且也非常的方便实用 为什么刷脸支付才刚入市 就大有取代扫码支付的趋势呢 其实很简单 刷脸支
  • idea编译级别设置

    方法一 File gt Project Structure gt Project File gt Settings gt Build Execution Deployment gt Compiler gt Java Compiler 方法二
  • sqli-labs26

    文章目录 一 审查源码 1 判断注入点和闭合方式 2 过滤方式 二 SQL注入 1 获取数据库 2 获取数据表 3 获取字段 双写绕过 anandd 大小写绕过And 括号绕过 ASCII编码绕过 20 0a绕过 内联注释 替换 如 and
  • 蓝桥杯提交代码每次都是运行出错,但自己在编辑器上运行没问题...

    问题描述 自己在eclipse上面跑的java题目是完全可以编译运行的 但是提交到系统中却一直是运行错误 检查了好久觉得自己没有哪里写错 解决办法 最后发现是自己给不同的题目分了类放在了不同的包下面 提交代码的时候没有把引入的包名注释掉 因
  • 移动BI应该怎么规划?每一个数据产品经理必看

    在移动化 大数据浪潮的今天 基于数据做决策应该是每一家公司的标配 每家公司都有专门负责数据的人 也都应该有一个BI部门 而移动BI 基于手机端随时随地进行数据查询和分析 更是BI中不可或缺的一部分 那么移动BI怎么做 我们按照 用户体验要素
  • 链式输送机传动装置设计(说明书+CAD图纸+PPT)

    摘要 齿轮传动是应用极为广泛和特别重要的一种机械传动形式 它可以用来在空间的任意轴之间传递运动和动力 目前齿轮传动装置正逐步向小型化 高速化 低噪声高可靠性和硬齿面技术方向发展 齿轮传动具有传动平稳可靠 传动效率高 一般可以达到94 以上
  • Qt中opengl使用swapBuffers()函数报错解决办法

    swapBuffers qt文档中方的翻译 用屏幕外缓冲区交换屏幕内容 仅当窗口小部件的格式指定双缓冲模式时 此方法才有效 通常 不需要显式调用此函数 因为它是在每个小部件重新绘制后 即每次执行paintGL 之后 自动完成的 我是在线程中
  • Visual Studio(VS) 编程推荐字体及设置

    菜单栏 工具 选项 选择Consolas就是最常见的编码字体了 在这个字体下的中英文标点和半角圆角符号也能有比较明显的区别
  • YARN之Container-什么是Container?

    在最基本的层面上 Container是单个节点上如RAM CPU核核磁盘等物理资源的集合 单个节点上 或者单个大节点 可以有多个Container 系统中的每个节点可以认为是由内存 如512MB或者1GB 和CPU的最小容量的多个Conta
  • gin-巧用Context传递多种参数

    目录 引言 1 巧妙包装gin Context为NewContext 2 在使用gin Use对每一个请求的Context进行组装 3 在路由绑定时解析出NewContext来为应用层函数提供参数 并且调用应用层函数 4 总结 引言 首先给