GoLang Gin实际使用

所有代码同步到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"

好的,我可以为您提供一些关于使用 Golang Gin 框架进行项目实战的建议。 首先,您需要安装 GolangGin 框架。安装过程可以参考官方文档进行操作。然后,您可以按照以下步骤进行项目实战: 1. 创建项目结构 在您的 GOPATH 目录下创建一个新的项目文件夹。通常情况下,您需要为项目创建以下子文件夹: ``` . ├── main.go ├── config │ ├── config.go │ └── ... ├── controller │ ├── home_controller.go │ └── ... ├── middleware │ ├── auth.go │ └── ... ├── model │ ├── user.go │ └── ... ├── router │ ├── router.go │ └── ... └── service ├── user_service.go └── ... ``` 2. 创建路由 在 router 文件夹创建一个 router.go 文件,并编写以下代码: ```go package router import ( "github.com/gin-gonic/gin" "your-project/controller" "your-project/middleware" ) func SetupRouter() *gin.Engine { r := gin.Default() // 间件 r.Use(middleware.AuthMiddleware()) // 路由 r.GET("/", controller.HomePageHandler) return r } ``` 在上面的代码,我们使用gin 框架gin.Default() 函数来创建一个默认的 gin.Engine 实例,并使用间件来进行身份验证。然后我们定义了一个路由,将根路径映射到 HomePageHandler 方法。 3. 创建控制器 在 controller 文件夹创建 home_controller.go 文件,并编写以下代码: ```go package controller import ( "github.com/gin-gonic/gin" "your-project/service" ) func HomePageHandler(c *gin.Context) { users := service.GetAllUsers() c.JSON(200, users) } ``` 在上面的代码,我们定义了一个 HomePageHandler 方法,它接收一个 gin.Context 对象作为参数,并使用 service 层的 GetAllUsers 函数获取所有用户的数据。然后我们使用 JSON 方法将数据以 JSON 格式返回给客户端。 4. 创建服务层 在 service 文件夹创建 user_service.go 文件,并编写以下代码: ```go package service import "your-project/model" func GetAllUsers() []*model.User { // TODO: 查询数据库获取所有用户数据 return []*model.User{} } ``` 在上面的代码,我们定义了一个 GetAllUsers 函数,它返回一个包含所有用户数据的切片。在实际项目,我们需要查询数据库来获取这些数据。 5. 创建模型 在 model 文件夹创建 user.go 文件,并编写以下代码: ```go package model type User struct { ID int `json:"id"` Name string `json:"name"` Age int `json:"age"` } ``` 在上面的代码,我们定义了一个 User 结构体,它包含三个字段:ID、Name 和 Age。这些字段将用于存储每个用户的信息。 6. 创建配置文件 在 config 文件夹创建 config.go 文件,并编写以下代码: ```go package config const ( DB_HOST = "localhost" DB_PORT = "3306" DB_USERNAME = "root" DB_PASSWORD = "password" DB_NAME = "your-database-name" ) ``` 在上面的代码,我们定义了一些常量,用于存储数据库配置信息。这些常量将在连接数据库时使用。 7. 连接数据库 在 service 层的 GetAllUsers 函数,我们需要连接数据库来获取所有用户数据。可以使用以下代码来连接 MySQL 数据库: ```go package service import ( "database/sql" "fmt" "your-project/config" "your-project/model" ) func GetAllUsers() []*model.User { // 连接数据库 db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", config.DB_USERNAME, config.DB_PASSWORD, config.DB_HOST, config.DB_PORT, config.DB_NAME, )) if err != nil { panic(err) } defer db.Close() // 查询所有用户数据 rows, err := db.Query("SELECT * FROM users") if err != nil { panic(err) } // 解析查询结果 users := []*model.User{} for rows.Next() { user := &model.User{} err := rows.Scan(&user.ID, &user.Name, &user.Age) if err != nil { panic(err) } users = append(users, user) } return users } ``` 在上面的代码,我们使用 sql.Open 函数来打开 MySQL 数据库连接。然后我们使用 db.Query 函数来查询所有用户数据,并使用 rows.Scan 函数将查询结果解析为 User 结构体的切片。 以上就是使用 Golang Gin 框架进行项目实战的流程。当然,在实际项目,您需要根据自己的需求进行相应的修改和扩展。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值