Gin框架路由拆分与注册详解析
Gin框架路由拆分与注册详解析
- 1.基本的路由注册
- 2.路由拆分成单独文件或包
- 3.路由拆分成多个文件
- 4.路由拆分到不同的APP
1.基本的路由注册
下面最基础的gin路由注册方式,适用于路由条目比较少的简单项目或者项目demo
// StatCost 是一个统计耗时请求耗时的中间件
func StatCost() gin.HandlerFunc {return func(c *gin.Context) {start := time.Now()c.Set("name", "小王子") // 可以通过c.Set在请求上下文中设置值,后续的处理函数能够取到该值// 调用该请求的剩余处理程序c.Next()// 不调用该请求的剩余处理程序// c.Abort()// 计算耗时cost := time.Since(start)log.Println(cost)}
}func helloHandler(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "Hello dahe!",})
}func main() {r := gin.Default()r.GET("/hello", helloHandler, StatCost())if err := r.Run(); err != nil {fmt.Println("startup service failed, err:%v\n", err)}
}
2.路由拆分成单独文件或包
当项目的规模增大后就不太适合继续在项目的main.go文件中去实现路由注册相关逻辑了,我们会倾向于把路由部分的代码都拆分出来,形成一个单独的文件或包:
我们在routers.go文件中定义并注册路由信息:
package mainimport ("github.com/gin-gonic/gin""net/http"
)func helloHandler(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "Hello dahe!",})
}func setupRouter() *gin.Engine {r := gin.Default()r.GET("/hello", helloHandler)return r
}
此时main.go中调用上面定义好的setupRouter函数:
package mainimport "fmt"func main() {r := setupRouter()if err := r.Run(); err != nil {fmt.Println("err:%v\n", err)}
}
3.路由拆分成多个文件
当我们的业务规模继续膨胀,单独的一个routers文件或包已经满足不了我们的需求了
因为我们把所有的路由注册都写在一个SetupRouter函数中的话就会太复杂了。
我们可以分开定义多个路由文件,例如:
gin_demo
├── go.mod
├── go.sum
├── main.go
└── routers├── blog.go└── shop.go
routers/shop.go中添加一个LoadShop的函数,将shop相关的路由注册到指定的路由器:
func LoadShop(e *gin.Engine) {e.GET("/hello", helloHandler)e.GET("/goods", goodsHandler)e.GET("/checkout", checkoutHandler)...
}
routers/blog.go中添加一个LoadBlog的函数,将blog相关的路由注册到指定的路由器:
func LoadBlog(e *gin.Engine) {e.GET("/post", postHandler)e.GET("/comment", commentHandler)...
}
在main函数中实现最终的注册逻辑如下:
func main() {r := gin.Default()routers.LoadBlog(r)routers.LoadShop(r)if err := r.Run(); err != nil {fmt.Println("startup service failed, err:%v\n", err)}
}
4.路由拆分到不同的APP
有时候项目规模实在太大,那么我们就更倾向于把业务拆分的更详细一些,例如把不同的业务代码拆分成不同的APP。
因此我们在项目目录下单独定义一个app目录,用来存放我们不同业务线的代码文件,这样就很容易进行横向扩展。大致目录结构如下:
gin_demo
├── app
│ ├── blog
│ │ ├── handler.go
│ │ └── router.go
│ └── shop
│ ├── handler.go
│ └── router.go
├── go.mod
├── go.sum
├── main.go
└── routers└── routers.go
其中app/blog/router.go用来定义blog相关的路由信息,具体内容如下:
func Routers(e *gin.Engine) {e.GET("/post", postHandler)e.GET("/comment", commentHandler)
}
app/shop/router.go用来定义shop相关路由信息,具体内容如下:
func Routers(e *gin.Engine) {e.GET("/goods", goodsHandler)e.GET("/checkout", checkoutHandler)
}
routers/routers.go中根据需要定义Include函数用来注册子app中定义的路由,Init函数用来进行路由的初始化操作:
type Option func(*gin.Engine)var options = []Option{}// 注册app的路由配置
func Include(opts ...Option) {options = append(options, opts...)
}// 初始化
func Init() *gin.Engine {r := gin.Default()for _, opt := range options {opt(r)}return r
}
main.go中按如下方式先注册子app中的路由,然后再进行路由的初始化:
func main() {// 加载多个APP的路由配置routers.Include(shop.Routers, blog.Routers)// 初始化路由r := routers.Init()if err := r.Run(); err != nil {fmt.Println("startup service failed, err:%v\n", err)}
}
相关文章:
Gin框架路由拆分与注册详解析
Gin框架路由拆分与注册详解析1.基本的路由注册2.路由拆分成单独文件或包3.路由拆分成多个文件4.路由拆分到不同的APP1.基本的路由注册 下面最基础的gin路由注册方式,适用于路由条目比较少的简单项目或者项目demo // StatCost 是一个统计耗时请求耗时的中间件 func…...
2020蓝桥杯真题凯撒加密 C语言/C++
题目描述 给定一个单词,请使用凯撒密码将这个单词加密。 凯撒密码是一种替换加密的技术,单词中的所有字母都在字母表上向后偏移 3 位后被替换成密文。即 a 变为 d,b 变为 e,⋯,w 变为z,x 变为 a࿰…...
taro+vue3小程序使用v-html渲染的内容为class写了样式无效
taro小程序如果是直接引入的一个less文件是包含scoped,只是当前页面采用。<script setup>import ./index.less</script><view v-html"itehtml" class"article-content"></view>let itehtml"<p class"line…...
MASK-RCNN网络介绍
目录前言一.MASK R-CNN网络1.1.RoIPool和RoIAlign1.2.MASK分支二.损失函数三.Mask分支预测前言 在介绍MASK R-CNN之前,建议先看下FPN网络,Faster-CNN和FCN的介绍:下面附上链接: R-CNN、Fast RCNN和Faster RCNN网络介绍FCN网络介绍…...
导航技术调研(CSDN_0023_20221217)
文章编号:CSDN_0023_20221217 目录 1. 惯性导航 2. 组合导航技术 3. 卡尔曼滤波 1. 惯性导航 惯性导航系统(INS-Inertial Navigation System)是上个世纪初发展起来的。惯性导航是一种先进的导航方法,但实现导航定位的原理却非常简单,它是…...
买卖股票的最佳时机 I II III IV
121. 买卖股票的最佳时机 自己的思路:采用求最长连续子串和题目的思路 class Solution {public int maxProfit(int[] prices) {if(prices.length 1) return 0;int[] nums new int[prices.length - 1];for(int i 0;i < prices.length - 1;i){nums[i] prices[…...
STM32—LCD1602
LCD1602(Liquid Crystal Display)是一种工业字符型液晶,能够同时显示 1602 即 32 字符(16列两行) 第 1 脚: VSS 为电源地 第 2 脚: VDD 接 5V 正电源 第 3 脚: VL 为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最…...
英雄算法学习路线
文章目录零、自我介绍一、关于拜师二、关于编程语言三、算法学习路线1、算法集训1)九日集训2)每月算法集训2、算法专栏3、算法总包四、英雄算法联盟1、英雄算法联盟是什么?2、如何加入英雄算法联盟?3、为何会有英雄算法联盟&#…...
【设计模式】备忘录模式和迭代器模式
备忘录模式和迭代器模式备忘录模式代码示例迭代器模式代码示例使用迭代器遍历集合的同时不能删除/增加元素总结备忘录模式 备忘录模式,也叫快照(Snapshot)模式。 在 GoF的《设计模式》⼀书中,备忘录模式是这么定义的:…...
rapidcsv 写csv文件实例
csv实质是一个文本文件,可以使用rapidcsv写文件操作,如下实例: 第一行实质是从-1行开始,列是从0开始 #include "rapidcsv.h" #include <string> using namespace std; void CMFCApplication1Dlg::OnBnClickedBu…...
数据库--进阶篇--9--存储引擎
MySQL体系结构 索引是在引擎层,所以不同的存储引擎,它的索引结构不同。 存储引擎简介 存储引擎就是存储数据、建立所以、更新/查询数据等技术的实现方式。存储引擎是基于表的,而不是基于库的,所以存储引擎也可以被称为表类型。 …...
物品的管理的隐私政策
本应用尊重并保护所有使用服务用户的个人隐私权。为了给您提供更准确、更有个性化的服务,本应用会按照本隐私权政策的规定使用和披露您的个人信息。但本应用将以高度的勤勉、审慎义务对待这些信息。除本隐私权政策另有规定外,在未征得您事先许可的情况下…...
深度解析首个Layer3 链 Nautilus Chain,有何优势?
以流支付为主要概念的Zebec生态,正在推动流支付这种新兴的支付方式向更远的方向发展,该生态最初以Zebec Protocol的形态发展,并从初期的Solana进一步拓展至BNB Chian以及Near上。与此同时,Zebec生态也在积极的寻求从协议形态向公链…...
配对变量t检验
区别双变量t检验,见:https://mp.csdn.net/postedit/100640098 配对变量为两两相关的变量:如敷药前后体重变化。 要求:两变量服从正态分布。 SPSS演练 打开数据文件:ptest.sav 载地址:https://download.c…...
蓝桥杯三月刷题 第八天
文章目录💥前言😉解题报告💥分数🤔一、思路:😎二、代码:💥回文日期🤔一、思路:😎二、代码:💥迷宫🤔一、思路:😎二、代码&a…...
EXCEL技能点3-常用技能1
1 引用格式 公式中引用单元格或者区域时,引用的类型可分为以下三种: 绝对引用 相对引用 混合引用 在Excel里,每个单元格都有一个编码,就像人的身份证一样,在Excel里是按照行列进行编码,例如A1就是第一列的第一行。 那么我们想要引…...
经典分类模型回顾16-AlexNet实现垃圾分类(Tensorflow2.0版)
AlexNet是2012年由亚历克斯克里斯托夫(Alex Krizhevsky)等人提出的一种卷积神经网络结构,它在ImageNet图像识别比赛中获得了第一名,标志着卷积神经网络的崛起。 AlexNet的结构包括8层网络,其中前5层为卷积层ÿ…...
vue3使用vuex
第一步安装: package.json { "name": "demo", "version": "0.1.0", "private": true, "scripts": { "serve": "vue-cli-service serve", "build": "vue-c…...
Java面向对象:抽象类的学习
本文介绍了抽象类的基本语法概念,什么是抽象类. Java中抽象类的语法,抽象类的特性 抽象类的作用(抽象类和普通类的区别) 用抽象类实现多态… 抽象类的学习一.什么是抽象类二.抽象类语法三.抽象类的特性四.抽象类的作用五. 抽象类实现多态一.什么是抽象类 在面向对象的概念中&am…...
modbus转profinet网关连接5台台达ME300变频器案例
通过兴达易控Modbus转Profinet(XD-MDPN100)网关改善网络场景,变频器有掉线或数据丢失报警,影响系统的正常运行,将5台 ME300变频器modbus转Profinet到1200PLC,通过网关还可以实现Profinet转modbus RTU协议转…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...
