【9.2】Golang后端开发系列--Gin路由定义与实战使用

文章目录

      • 一、Gin 框架路由的基本定义方式
        • 1. 简单路由创建
        • 2. 路由参数
        • 3. 查询参数
      • 二、商业大项目中的路由定义和服务调用
        • 1. 路由模块化
        • 2. 路由组和中间件
        • 3. 中间件的使用
        • 4. 服务层调用
        • 5. 错误处理
        • 6. 版本控制
        • 7. 路由注册

一、Gin 框架路由的基本定义方式

1. 简单路由创建

使用 gin.Default() 创建一个带有默认中间件的路由引擎,然后通过 GET, POST, PUT, DELETE 等方法来定义不同 HTTP 方法的路由。

package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {// 创建带有默认中间件的路由引擎r := gin.Default()// 定义 GET 请求的路由r.GET("/hello", func(c *gin.Context) {c.String(http.StatusOK, "Hello, World!")})// 启动服务r.Run(":8080")
}
2. 路由参数

使用 : 来定义路由参数,通过 c.Param() 方法从请求中提取参数。

r.GET("/users/:userID", func(c *gin.Context) {userID := c.Param("userID")c.String(http.StatusOK, "User ID: %s", userID)
})
3. 查询参数

使用 c.Query() 方法来获取查询参数。

r.GET("/search", func(c *gin.Context) {query := c.Query("q")c.String(http.StatusOK, "Search query: %s", query)
})

二、商业大项目中的路由定义和服务调用

1. 路由模块化

为了使代码结构更清晰和易于维护,将路由定义分散到不同的文件和包中。

routes/user.go

package routesimport ("github.com/gin-gonic/gin""yourproject/services"
)func SetupUserRoutes(r *gin.RouterGroup) {r.GET("/", services.GetAllUsers)r.GET("/:id", services.GetUserByID)r.POST("/", services.CreateUser)r.PUT("/:id", services.UpdateUser)r.DELETE("/:id", services.DeleteUser)
}

services/user.go

package servicesimport ("github.com/gin-gonic/gin""net/http"
)func GetAllUsers(c *gin.Context) {// 调用数据访问层或其他服务层的函数来获取用户列表users, err := userService.GetAll()if err!= nil {c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch users"})return}c.JSON(http.StatusOK, users)
}func GetUserByID(c *gin.Context) {id := c.Param("id")user, err := userService.GetByID(id)if err!= nil {c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})return}c.JSON(http.StatusOK, user)
}func CreateUser(c *gin.Context) {var newUser Userif err := c.BindJSON(&newUser); err!= nil {c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"})return}if err := userService.Create(newUser); err!= nil {c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create user"})return}c.JSON(http.StatusCreated, gin.H{"message": "User created successfully"})
}func UpdateUser(c *gin.Context) {id := c.Param("id")var updatedUser Userif err := c.BindJSON(&updatedUser); err!= nil {c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"})return}if err := userService.Update(id, updatedUser); err!= nil {c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update user"})return}c.JSON(http.StatusOK, gin.H{"message": "User updated successfully"})
}func DeleteUser(c *gin.Context) {id := c.Param("id")if err := userService.Delete(id); err!= nil {c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete user"})return}c.JSON(http.StatusOK, gin.H{"message": "User deleted successfully"})
}
2. 路由组和中间件

使用路由组来组织相关的路由,并且可以为路由组添加中间件。

routes/router.go

package routesimport ("github.com/gin-gonic/gin""yourproject/middleware""yourproject/services"
)func SetupRoutes() *gin.Engine {r := gin.Default()// 公共中间件,例如日志、认证等r.Use(middleware.Logger(), middleware.Authenticate())// 用户路由组users := r.Group("/users")SetupUserRoutes(users)// 产品路由组products := r.Group("/products")SetupProductRoutes(products)return r
}
3. 中间件的使用

中间件可以在请求处理的不同阶段执行逻辑,如日志记录、认证、授权、错误处理等。

middleware/logger.go

package middlewareimport ("github.com/gin-gonic/gin""log""time"
)func Logger() gin.HandlerFunc {return func(c *gin.Context) {start := time.Now()c.Next()duration := time.Since(start)log.Printf("%s %s %s %v", c.Request.Method, c.Request.URL.Path, c.Writer.Status(), duration)}
}

middleware/authenticate.go

package middlewareimport ("github.com/gin-gonic/gin""net/http"
)func Authenticate() gin.HandlerFunc {return func(c *gin.Context) {// 检查用户是否认证,例如通过 token 验证if!isAuthenticated(c) {c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})return}c.Next()}
}func isAuthenticated(c *gin.Context) bool {// 实际的认证逻辑,例如检查请求头中的 tokenauthHeader := c.GetHeader("Authorization")if authHeader == "" {return false}// 更复杂的验证逻辑,如验证 token 的有效性return true
}
4. 服务层调用

将业务逻辑封装在服务层,路由处理函数负责调用相应的服务。

services/user_service.go

package servicesimport ("errors"
)type UserService struct{}func (s *UserService) GetAll() ([]User, error) {// 模拟从数据库或其他数据源获取用户列表// 这里应该调用实际的数据访问层函数users := []User{{ID: "1", Name: "Alice"},{ID: "2", Name: "Bob"},}return users, nil
}func (s *UserService) GetByID(id string) (*User, error) {// 模拟根据 ID 获取用户// 这里应该调用实际的数据访问层函数if id == "1" {return &User{ID: "1", Name: "Alice"}, nil}return nil, errors.New("User not found")
}func (s *UserService) Create(user User) error {// 模拟创建用户// 这里应该调用实际的数据访问层函数return nil
}func (s *UserService) Update(id string, user User) error {// 模拟更新用户// 这里应该调用实际的数据访问层函数return nil
}func (s *UserService) Delete(id string) error {// 模拟删除用户// 这里应该调用实际的数据访问层函数return nil
}
5. 错误处理

在路由处理函数和服务层中都要进行错误处理,确保将错误信息正确返回给客户端。

func GetUserByID(c *gin.Context) {id := c.Param("id")user, err := userService.GetByID(id)if err!= nil {c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})return}c.JSON(http.StatusOK, user)
}
6. 版本控制

对于 API 的不同版本,可以使用路由组进行管理。

func SetupRoutes() *gin.Engine {r := gin.Default()v1 := r.Group("/v1")SetupV1Routes(v1)v2 := r.Group("/v2")SetupV2Routes(v2)return r
}
7. 路由注册

main 函数中注册路由并启动服务。

package mainimport ("yourproject/routes"
)func main() {r := routes.SetupRoutes()r.Run(":8080")
}

通过上述方式,在商业大项目中使用 Gin 框架时,可以将路由定义、中间件、服务调用和错误处理等部分分离,实现清晰的分层架构,提高代码的可维护性和可扩展性。这样做有助于团队协作开发,并且方便对不同功能模块进行单独测试和优化。同时,合理使用路由组和中间件可以确保不同路由的逻辑隔离和功能复用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/68210.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32 FreeRTOS移植

目录 FreeRTOS源码结构介绍 获取源码 1、 官网下载 2、 Github下载 源码结构介绍 源码整体结构 FreeRTOS文件夹结构 Source文件夹结构如下 portable文件夹结构 RVDS文件夹 MemMang文件夹 FreeRTOS在基于寄存器项目中移植步骤 目录添加源码文件 工程添加源码文件 …

【算法】回溯法

回溯法(Backtracking)是一种通过系统地搜索问题的解空间来找到所有可能结果或最佳解的算法设计范式。它广泛应用于解决各种组合优化问题,比如图的着色、数独求解、八皇后问题、旅行商问题等。 在程序中,回溯法通常表现为递归函数…

【ASP.NET学习】Web Forms创建Web应用

文章目录 什么是 Web Forms?ASP.NET Web Forms - HTML 页面用 ASP.NET 编写的 Hello RUNOOB.COM它是如何工作的?经典 ASP ASP.NET Web Forms - 服务器控件经典 ASP 的局限性ASP.NET - 服务器控件ASP.NET - HTML 服务器控件ASP.NET - Web 服务器控件ASP.N…

Linux 常见运营维护,从安装软件开始,到mysql,php,redis,tomcat等软件安装,配置,优化,持续更新中。。。

下载centos7 CentOS 7 完整版(DVD): https://mirrors.aliyun.com/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-2009.isoCentOS 7 最小化版(Minimal): https://mirrors.aliyun.com/centos/7/isos/x86_64/C…

用户界面软件05

已知应用 几乎所有的流行的用户界面架构都使用这种模式。我在这里举三个例子: 1. Seeheim 用户界面架构的特点是有一个应用核心的领域层和一个用户界面层。后者 被分为两层,叫做表示层和对话控制层。因为这个架构和面向事务系统有渊源,没有…

从玩具到工业控制--51单片机的跨界传奇【2】

咱们在上一篇博客里面讲解了什么是单片机《单片机入门》,让大家对单片机有了初步的了解。我们今天继续讲解一些有关单片机的知识,顺便也讲解一下我们单片机用到的C语言知识。如果你对C语言还不太了解的话,可以看看博主的C语言专栏哟&#xff…

如何通过openssl生成.crt和.key

生成 .crt(证书文件)和 .key(私钥文件)的过程通常涉及使用加密工具或库来创建密钥对,并生成证书请求,最终由证书颁发机构(CA)或自签名生成证书。以下是生成 .crt 和 .key 文件的详细…

华为2024嵌入式研发面试题

01 你认为最好的排序算法是什么? 在实际的编程中,最好的排序算法要根据实际需求和数据规模来选择,因为每种排序算法都有其优势和劣势。以下是一些常见排序算法及其优缺点: 冒泡排序 冒泡排序是一种简单直观的排序算法&#xff0…

LVGL移植高通点阵字库GT30L24A3W

字库芯片: GT30L24A3W MCU:STM32F429 LVGL版本:V8.4 一、实现gt_read_data() 和 r_dat_bat() 请参考下面视频 如何在32位MCU上使用高通点阵字库_哔哩哔哩_bilibili 高通字库使用教程(1)硬件链接与注意事项部分_哔哩哔哩_bilibili 高通字库使用教程(2)SPI底层函数使用_哔哩…

C# OpenCV机器视觉:转速测量

在一个看似平常却又暗藏神秘能量的日子里,阿杰正在他那充满科技感的实验室里,对着一堆奇奇怪怪的仪器发呆。突然,手机铃声如一道凌厉的剑气划破寂静,原来是工厂的赵厂长打来的紧急电话:“阿杰啊,咱们工厂新…

Git | git revert命令详解

关注:CodingTechWork 引言 Git 是一个强大的版本控制工具,广泛应用于现代软件开发中。它为开发人员提供了多种功能来管理代码、协作开发和版本控制。在 Git 中,有时我们需要撤销或回退某些提交,而git revert 是一个非常有用的命令…

【Vue】Vue组件--上

目录 一、组件基础 二、组件的嵌套关系 1. 基础架构 2. 嵌套 三、组件注册方式 1. 局部注册: 2. 全局注册: 四、组件传递数据 1. 基础架构 2. 传递多值 3. 动态传递数据 五、组件传递多种数据类型 1. Number 2. Array 3. Object 六、组…

unity下载newtonsoft-json

Package Manager,输入com.unity.nuget.newtonsoft-json 右键Assets-Reinport All

SpringBoot项目实战(40)--Beetl网页开发在控制层使用通用方法映射前端不同路径的网页

在SpringBoot中使用Beetl做前端页面,后端如何使用Controller映射前端不同的页面,不需要为每个前端页面单独增加控制层方法? 因为前端页面比较多,每个前端页面对应一个独立Controller方法也是不现实的,总不能每增加一个…

【自动化测试】—— Appium安装配置保姆教程(图文详解)

目录 一. 环境准备 二. JDK安装 1. 下载JDK 2. 安装JDK 3. 配置环境 4. 验证安装 三. Android SDK安装 1. 下载Android SDK 2. 安装Android SDK 3. 安装工具 4. 配置环境 5. 验证安装 四. NodeJS安装 1. 下载NodeJS 2. 安装NodeJS 3. 验证安装 4. 安装淘宝镜像…

Oracle 终止正在执行的SQL

目录 一. 背景二. 操作简介三. 投入数据四. 效果展示 一. 背景 项目中要求进行性能测试,需要向指定的表中投入几百万条数据。 在数据投入的过程中发现投入的数据不对,需要紧急停止SQL的执行。 二. 操作简介 👉需要DBA权限👈 ⏹…

二、智能体强化学习——深度强化学习核心算法

2.1 DQN 系列及其改进 2.1.1 背景与动机 在经典强化学习中(如 Q-Learning),如果状态空间或动作空间非常大乃至连续,那么用一个表格来存储 Q ( s , a ) Q(s,a) Q(s,

【SH】Xiaomi9刷Windows10系统研发记录 、手机刷Windows系统教程、小米9重装win10系统

文章目录 参考资料云盘资料软硬件环境手机解锁刷机驱动绑定账号和设备解锁手机 Mindows工具箱安装工具箱和修复下载下载安卓和woa资源包第三方Recovery 一键安装Windows准备工作创建分区安装系统 效果展示Windows和Android一键互换Win切换安卓安卓切换Win 删除分区 参考资料 解…

PHP语言的多线程编程

PHP语言的多线程编程 引言 在现代Web开发中,PHP以其简洁和易用性广受欢迎。它常用于构建动态网站和应用程序。然而,PHP本身是单线程的,这意味着它在处理多个任务时可能会受到性能限制。随着互联网的发展,对高并发、高可用性和实…

MySQL从库 Last_SQL_Errno: 1197 问题处理过程

记录一个遇到过的错误,今天整理一下。 问题 MySQL error code MY-001197 (ER_TRANS_CACHE_FULL): Multi-statement transaction required morethan max_binlog_cache_size bytes of storage; increase this mysqld variable and try again报错很明显是max_binlog_…