GoLang Gin实际使用

server/2024/9/20 7:15:44/ 标签: gin

所有代码同步到Admin/gitDemo - Gitee.comgins/CsdnLink/icons/icon-default.png?t=N7T8" alt="icon-default.png?t=N7T8" />https://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 routerimport ("github.com/gin-gonic/gin"
)func APIRouter() *gin.Engine {r := gin.Default()v1 := r.Group("//v1")api := v1.Group("/api")userRoutes := UserRoutesuserRoutes(api)return r
}

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

package serviceimport ("ginDemo/internal/response""github.com/gin-gonic/gin"
)type Response response.NorResponsetype UserService interface {Login(ctx *gin.Context) anyLogout(ctx *gin.Context) anyGetUser(ctx *gin.Context) anyAddUser(ctx *gin.Context) anyUpdateUser(ctx *gin.Context) anyDeleteUser(ctx *gin.Context) any
}

4.同级目录创建Imp

指定UserService得注入方法为ServiceImp

package serviceimport ("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 controllerimport ("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 routerimport (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.ppmy.cn/server/27727.html

相关文章

kube-prometheus部署到 k8s 集群

文章目录 **修改镜像地址****访问配置****修改 Prometheus 的 service****修改 Grafana 的 service****修改 Alertmanager 的 service****安装****Prometheus验证****Alertmanager验证****Grafana验证****卸载****Grafana显示时间问题** 或者配置ingress添加ingress访问grafana…

「C++ 类和对象篇 15」C++中的私有成员

目录 一、C中私有成员的访问权限 二、私有成员的命名规范 三、C对于私有成员的访问是由编译器来检查的 一、C中私有成员的访问权限 C私有成员访问权限是基于类的,而不是基于对象的。 在 C 中,当你在类的成员函数内部访问私有成员时无论这个私有成员是属…

JavaScript基础(二)

JS语法结构——引入方式 js很明显可以是一个后缀名为js的文件&#xff0c;js的引入方式和css一样&#xff0c;也有三种方式。 1.外部 使用script表现&#xff0c;只不过增加一个src属性&#xff0c;把js文件的路径src属性中。 <script src "js文件路径">&l…

如何保证每次画出的都同一张人脸?AI绘画Stable Diffusion的Reference only教程

Ai绘画有一个很现实的问题&#xff0c;要保证每次画出的都是同一个人物的话&#xff0c;很费劲。 Midjourney就不必说了&#xff0c;人物的高度一致性一直得不到很好的解决。而在Stable Diffusion&#xff08;SD&#xff09;中&#xff0c;常用办法是通过同一个Seed值&#xf…

【PC游戏】【World of Warcraft 魔兽世界(法语版)】怀旧版 CD-ROM 安装及使用记录(一)

一、前言 正值最近暴雪和网易重修旧好之时&#xff0c;笔者在新加坡从一个宅男朋友nerd bro那里淘到了一套法语版的World of Warcraft&#xff0c;共5张CD-ROM光碟。该套光碟的发行年份是2005年&#xff0c;于欧盟制造。推荐的操作系统是Windows 2000或者Windows XP或者Mac OS…

python 笔记:cls VS self

cls&#xff1a; 用于类方法&#xff1a; cls 通常作为类方法&#xff08;用 classmethod 装饰&#xff09;中的第一个参数。它指代调用该方法的类本身&#xff0c;无论该类有没有被实例化访问类级别的属性和方法 通过 cls&#xff0c;可以访问类级别的属性和方法。可以通过 c…

[第五空间-2021]yet_another_mysql_injection

title:[第五空间 2021]yet_another_mysql_injection 查看网页源码 访问view-source:node4.anna.nssctf.cn:28356/?source 得到题目源码 <?php include_once("lib.php"); function alertMes($mes,$url){die("<script>alert({$mes});location.href{…

android 判断文件是否存在

在 Android 中&#xff0c;你可以使用 java.io.File 类来判断一个文件是否存在。下面是一个简单的示例代码&#xff1a; import java.io.File; public class FileChecker { public static boolean isFileExist(String filePath) { File file new File(fi…

【Jenkins】持续集成与交付 (五):Jenkins用户权限管理

🟣【Jenkins】持续集成与交付 (五):Jenkins用户权限管理 1、安装插件(Role-based Authorization Strategy)2、开启权限全局安全配置3、创建角色4、创建用户5、给用户分配角色6、测试权限💖The Begin💖点点关注,收藏不迷路💖 1、安装插件(Role-based Authorization …

word 表格 文字 上下居中

问题 word 表格 文字 上下居中 详细问题 笔者进行word 文档编辑&#xff0c;对于表格中的文本内容&#xff0c;如何进行上下居中&#xff1f; 解决方案 步骤1、选中需要进行操作的单元格 步骤2、右键 → \rightarrow →点击表格属性 步骤3、依次点击单元格 → \rightar…

12、Flink 的 Keyed State 代码示例

1、KeyedState 用例 import org.apache.flink.api.common.functions.AggregateFunction; import org.apache.flink.api.common.functions.ReduceFunction; import org.apache.flink.api.common.state.*; import org.apache.flink.api.common.typeinfo.TypeHint; import org.ap…

Java中的模版方法设计模式详解

Java中的模版方法设计模式详解 在Java编程中&#xff0c;设计模式是一种解决常见问题的最佳实践。其中&#xff0c;模版方法设计模式是一种行为设计模式&#xff0c;它定义了一个操作中的算法骨架&#xff0c;而将一些步骤延迟到子类中。这样可以使子类在不改变算法结构的情况…

社交媒体数据恢复:Soul

Soul数据恢复方法 在Soul这款社交软件中&#xff0c;如果您的聊天记录不小心被删除&#xff0c;是否还能恢复呢&#xff1f;以下是根据搜索结果整理出的Soul数据恢复方法。 方法一&#xff1a;使用Soul的备份和恢复功能 开启备份功能&#xff1a;首先&#xff0c;您需要确保…

PS证件照

证件照尺寸 小一寸&#xff1a;2.2cm*3.3cm 一寸&#xff1a;2.5cm*3.5cm 像素413*295 &#xff08;分辨率为300像素/英寸&#xff09; 比例5&#xff1a;7 二寸&#xff1a;3.5cm*4.9cm 二寸照相比例是4&#xff1a;3&#xff0c;像素是626*413 蓝底&#xff1a;R&a…

Java面试八股之简述Java中assert的作用

简述Java中assert的作用 Java中的assert关键字用于在代码中插入断言&#xff08;Assertion&#xff09;&#xff0c;断言是一种在开发和测试阶段用于验证程序内部状态或假设的机制。其主要作用包括&#xff1a; 条件检查&#xff1a; assert语句用于在特定代码点上检查一个布…

【prometheus】监控MySQL并实现可视化

目录 一、概述 1.1下载解压mysqld_exporter 1.2创建MySQL授权用户 1.3配置my.cnf 1.4启动mysqld_exporter 1.5prometheus配置修改 二、Grafana展示 【Prometheus】概念和工作原理介绍_prometheus工作原理 【Prometheus】k8s集群部署node-exporter 【prometheus】k8s集…

OneFlow快速上手:深度学习初学者必备【AI写作】

首先&#xff0c;这篇文章是基于笔尖AI写作进行文章创作的&#xff0c;喜欢的宝子&#xff0c;也可以去体验下&#xff0c;解放双手&#xff0c;上班直接摸鱼~ 按照惯例&#xff0c;先介绍下这款笔尖AI写作&#xff0c;宝子也可以直接下滑跳过看正文~ 笔尖Ai写作&#xff1a;…

Mysql优化之参数调优

前言 MySQL参数优化是针对数据库配置参数的调整和优化&#xff0c;以提高数据库系统的性能、稳定性和可用性。它和Mysql的应用环境例如项目的用户量在线情况、访问情况、存储资源量等以及服务硬件配置都有关系&#xff0c;优化也不可能一次性完成&#xff0c;需要不断的观察以…

Flink 实时数仓(一)【实时数仓离线数仓对比】

前言 昨天技术面的时候&#xff0c;面试官说人家公司现在用的都是最新的技术&#xff0c;比如 Doris 等一些最新的工具&#xff0c;确实这些课是学校永远不会开设的&#xff0c;好在他说去了会带着我做一做。可是 ...... 学院这边确实不允许放人&#xff0c;唉&#xff0c;可惜…

qt对话框功能介绍

1、颜色对话框 //方式一QColor color QColorDialog::getColor(Qt::red, this, QString::fromLocal8Bit("颜色对话框"),QColorDialog::ShowAlphaChannel);qDebug() <<"color:" <<color;//方式二QColorDialog dialog(Qt::red, this); // 创建对…