GoLang Gin实际使用

news2024/11/19 23:34:06

所有代码同步到Admin/gitDemo - Gitee.comicon-default.png?t=N7T8https://gitee.com/mec-deployment-team_0/git-demo/tree/dev/

1.创建Gin框架

一般设计一个常规的web项目,都需要以下几个模块

  1. runApp 主函数,运行整个项目
  2. routes 路由控制,管理跳转以及路由分组
  3. controllers 管理路由跳转后执行的逻辑
  4. service/serviceImp 管理执行的具体业务,依赖注入时可以做实体接口分离
  5. dao 管理数据库连接,数据库控制
  6. filters 中间件,全局,路由分组中注入额外的执行方法,例如token,cors
  7. logs 日志系统,交给运维处理
  8. configs 额外的属性配置,例如数据库连接信息,文件上传大小,线程池大小

以上就是常规的后端项目基本需要的内容,随着业务的变深入,可以在加深,例如公有的utils,返回的异常code解释等,但是希望保留核心,做项目之前不用像无头苍蝇一样先做出来,按个人喜好设计就行了,后期做目录优化也行。

设计了一个简单的目录结构如下

├─cmd
│  └─ginDemo   //与项目名称一致,存放主函数main
├─deployments //部署文件
├─docs  //swagger信息
├─internal  // 放置项目私有信息
│  ├─config  //数据库等配置
│  ├─dao  // 数据库执行业务,也可以放在pkg内
│  ├─handler  // 中间件,处理切面业务
│  ├─model  // 模型,做数据库映射
│  ├─requests  // 请求格式校验
│  ├─responses // 返回信息校验
│  └─src  // 信息资源
├─pkg // 显示内容
│  ├─router  // 路由处理
│  ├─server  // 具体业务
│  │  ├─controller  // 控制器
│  │  └─service  // 业务接口,解耦
│  │      └─serviceImp  // 实际业务,可以与service合并
│  └─storage  // redis等处理
└─utils  // 共享工具类,转化,json处理等 

以上为我个人设计的 一个项目结构,看似非常多,但是主核心为三个

  1. cmd 存放主函数
  2. interval 存放model等不开放的模型信息
  3. pkg 存放与前端交互的实际业务

其余的内容一般在以后都可能会遇到,因此暂时不删除。这个项目与springboot的项目结构基本类似,一般常用于实际的业务中,关注点在于,server可能会很多,因此量大了之后要分不同模块的app进行切分,不然不好处理。

2.创建MVC主流程

Gin有几个缺点

  1. 不能像java一样可以直接在方法上添加路由注解,导致路由需要在route内进行集中匹配
  2. 不能添加service注解,导致需要在controller类里进行service匹配,费时费力
  3. 一般serive和Imp不分家,耦合性比较高
  4. 由于没有类,所以用struct代替类,每个方法前添加struct指针去指定方法归属

但是又几个优点

  1. 极佳的启停速度,开启时间与flask,springboot相比简直光速
  2. 没有java脱了裤子放屁的@lombok,结构体直接一步搞定model
  3. 拦截器过滤器都统一成为handler,触发机制简单
  4. 并发量极大,但是对我来说没什么感觉

1.创建main

func main() {
	r := router.APIRouter()
	err := r.Run(":8080")
	if err != nil {
		return
	}
}

2.创建router

package router

import (
	"github.com/gin-gonic/gin"
)

func APIRouter() *gin.Engine {
	r := gin.Default()
	v1 := r.Group("//v1")
	api := v1.Group("/api")

	userRoutes := UserRoutes
	userRoutes(api)
	return r
}

3.创建service接口(没啥用)

package service

import (
	"ginDemo/internal/response"
	"github.com/gin-gonic/gin"
)

type Response response.NorResponse

type UserService interface {
	Login(ctx *gin.Context) any
	Logout(ctx *gin.Context) any
	GetUser(ctx *gin.Context) any
	AddUser(ctx *gin.Context) any
	UpdateUser(ctx *gin.Context) any
	DeleteUser(ctx *gin.Context) any
}

4.同级目录创建Imp

指定UserService得注入方法为ServiceImp

package service

import (
	"github.com/gin-gonic/gin"
)

type UserServiceImp struct{}

func NewUserService() UserService {
	return &UserServiceImp{}
}

func (receiver *UserServiceImp) Login(ctx *gin.Context) any {
	return "ok"
}
func (receiver *UserServiceImp) Logout(ctx *gin.Context) any {
	return Response{}
}
func (receiver *UserServiceImp) GetUser(ctx *gin.Context) any {
	return Response{}
}
func (receiver *UserServiceImp) AddUser(ctx *gin.Context) any {
	return Response{}
}
func (receiver *UserServiceImp) UpdateUser(ctx *gin.Context) any {
	return Response{}
}
func (receiver *UserServiceImp) DeleteUser(ctx *gin.Context) any {
	return Response{}
}

5.创建controller

package controller

import (
	"ginDemo/pkg/server/service"
	"github.com/gin-gonic/gin"
	"net/http"
)

// UserController 定义结构体
type UserController struct {
	userService service.UserService
}

// NewUserController 依赖注入userService,userService通过Newxxx依赖注入
func NewUserController(UserService service.UserService) *UserController {
	return &UserController{userService: UserService}
}

// Login 指定结构体对应的方法
func (u *UserController) Login(ctx *gin.Context) {
	response := u.userService.Login(ctx)
	ctx.JSON(http.StatusOK, response)
}

6.routes关联方法

依赖注入转为new了,有种僵尸变人得感觉

package router

import (
	controller "ginDemo/pkg/server/controller"
	"ginDemo/pkg/server/service"
	"github.com/gin-gonic/gin"
)

func UserRoutes(r *gin.RouterGroup) {
	userService := service.NewUserService()
	userController := controller.NewUserController(userService)
	r.GET("/user/login", userController.Login)
}

okk,运行即可得到结果

[GIN-debug] GET    /v1/api/user/login        --> ginDemo/pkg/server/controller.(*UserController).Login-fm (3 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :8080
[GIN] 2024/04/28 - 22:29:34 | 200 |       707.6µs |             ::1 | GET      "/v1/api/user/login"
[GIN] 2024/04/28 - 22:37:09 | 404 |            0s |             ::1 | GET      "/"
[GIN] 2024/04/28 - 22:37:17 | 404 |            0s |             ::1 | GET      "/v1/api/login"
[GIN] 2024/04/28 - 22:37:25 | 200 |            0s |             ::1 | GET      "/v1/api/user/login"

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

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

相关文章

kubectl_入门_Pod调整

Pod调度 在默认情况下,一个pod在哪个node节点上运行,是由scheduler组件采用相应的算法计算出来的,这个过程是不受人工控制的。 但是在实际过程中,这并不满足需求,因为很多情况下,我们想控制某些pod到达某…

基于昇腾AI | 英码科技EA500I使用AscendCL实现垃圾分类和视频物体分类应用

现如今,人工智能迅猛发展,AI赋能产业发展的速度正在加快,“AI”的需求蜂拥而来,但AI应用快速落地的过程中仍存在很大的挑战:向下需要适配的硬件,向上需要完善的技术支持,两者缺一不可。 基于此&…

【C语言】深入了解文件:简明指南

🌈个人主页:是店小二呀 🌈C语言笔记专栏:C语言笔记 🌈C笔记专栏: C笔记 🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅 文章目录 一、文件的概念1.1 文件名:1.2 程序文件和数据文件 二、数据文…

香港上市现货比特币及以太坊ETF,首日交易量不及预期

原创 | 刘教链 在BTC(比特币)继续回调至61k一线,眼见就要在连续7个月收涨后,终于迎来一个收跌的4月之际,香港如期上市了现货比特币ETF和以太坊ETF,成为全球继美国推出现货比特币ETF之后,亚洲首个…

Aker(安碁科技)晶振产品应用和选型

一、石英晶体振荡器简介 在电子电路系统中,特定的动作需要严格按照一定的顺序进行,以确保数据被正确处理和操作,时钟信号就成了系统工作的重要引导者。而且在多模块复杂电路系统中,为了确保不同功能模块能协调一致地工作&#xf…

网络安全是智能汽车下一个要卷的方向?

2024年一季度,中国汽车市场延续了2023年的风格,核心就是「卷」。 2023年,我国汽车市场爆发「最强价格战」,燃油车的市场空间不断被挤压,如今只剩下最后一口气。近日乘联会发布4月1-14日最新数据,新能源&am…

ARM功耗管理背景及挑战

安全之安全(security)博客目录导读

使用 scikit-learn 进行机器学习的基本原理-2

介绍 scikit-learn 估计器对象 每个算法都通过“Estimator”对象在 scikit-learn 中公开。 例如,线性回归是:sklearn.linear_model.LinearRegression 估计器参数:估计器的所有参数都可以在实例化时设置: 拟合数据 让我们用 nump…

频谱模拟器

频谱模拟器,特别是模拟频谱仪,是一种基于特定原理的频谱分析工具。以下是对其的详细介绍: 工作原理: 模拟频谱仪的工作原理主要基于频率转换原理,包括两个关键步骤:信号混频和滤波分析。 信号混频&#xf…

el-table-column 表格列自适应宽度的组件封装说明

针对组件业务上的需求,需要给 el-table-column 加上限制,需保证表头在一行展示,部分列的内容要一行展示,自适应单项列的宽度; 1、先计算数据渲染后的 el-table-column 文本宽度; 因列表的有些数据需要做到…

OpenCV的图像矩(64)

返回:OpenCV系列文章目录(持续更新中......) 上一篇:OpenCV如何为等值线创建边界旋转框和椭圆(63) 下一篇 :OpenCV系列文章目录(持续更新中......) Image Moments(图像矩)是 OpenCV 库中的一个…

后端方案设计文档结构模板可参考

文章目录 1 方案设计文档整体结构2 方案详细设计2.1 概要设计2.2 详细设计方案2.2.1 需求分析2.2.2 业务流程设计2.2.3 抽象类:实体对象建模2.2.4 接口设计2.2.5 存储设计 1 方案设计文档整体结构 一,现状:把项目的基本情况和背景都说清楚&a…

Golang | Leetcode Golang题解之第60题排列序列

题目&#xff1a; 题解&#xff1a; func getPermutation(n int, k int) string {factorial : make([]int, n)factorial[0] 1for i : 1; i < n; i {factorial[i] factorial[i - 1] * i}k--ans : ""valid : make([]int, n 1)for i : 0; i < len(valid); i {…

如何避免被恶意攻击的IP地址

随着互联网的普及和发展&#xff0c;网络安全问题日益受到关注&#xff0c;恶意攻击成为网络安全的一大威胁。而IP地址作为网络通信的基础&#xff0c;常常成为恶意攻击的目标之一。本文将探讨如何避免被恶意攻击的IP地址&#xff0c;提高网络安全水平。 1. 定期更新安全补丁 …

AC+AP三层组网实验(华为)

一&#xff0c;技术简介 APAC架构是一种常见的无线局域网&#xff08;WLAN&#xff09;组网方式&#xff0c;主要由接入点&#xff08;Access Point&#xff0c;简称AP&#xff09;和接入控制器&#xff08;Access Controller&#xff0c;简称AC&#xff09;组成。 在APAC架构…

Stable Diffusion教程:额外功能/后期处理/高清化

"额外功能"对应的英文单词是Extras&#xff0c;算是直译。但是部分版本中的翻译是“后期处理”或者“高清化”&#xff0c;这都是意译&#xff0c;因为它的主要功能是放大图片、去噪、修脸等对图片的后期处理。注意这里边对图片的处理不是 Stable Diffusion 本身的能…

使用docker创建rocketMQ主从结构,使用

1、 创建目录 mkdir -p /docker/rocketmq/logs/nameserver-a mkdir -p /docker/rocketmq/logs/nameserver-b mkdir -p /docker/rocketmq/logs/broker-a mkdir -p /docker/rocketmq/logs/broker-b mkdir -p /docker/rocketmq/store/broker-a mkdir -p /docker/rocketmq/store/b…

Python+PYGObject/PYGtk+CSS样式--2024python示例

隔久点不用老是会忘&#xff0c;留个笔记。。 PythonPYGObject/PYGtk&#xff0c;加载 CSS 样式的演示代码 demo 运行的效果截图&#xff1a; #!/usr/bin/env python3 import sys import gigi.require_version("Gtk", "3.0") from gi.repository import …

飞书API(6):使用 pandas 处理数据并写入 MySQL 数据库

一、引入 上一篇了解了飞书 28 种数据类型通过接口读取到的数据结构&#xff0c;本文开始探讨如何将这些数据写入 MySQL 数据库。这个工作流的起点是从 API 获取到的一个完整的数据&#xff0c;终点是写入 MySQL 数据表&#xff0c;表结构和维格表结构类似。在过程中可以有不同…

大型企业总分支多区域数据传输,效率为先还是安全为先?

大型企业为了业务拓展需要&#xff0c;会在全国乃至全球各地设立分公司和办事机构&#xff0c;以便更好地处理当地事务&#xff0c;并进行市场的开拓和客户维护&#xff0c;此时&#xff0c;企业内部就衍生出了新的业务需求&#xff0c;即多区域数据传输。 多区域很难准确定义&…