使用 gin-api-mono 创建简单的 TODO 服务

关注公众号【爱发白日梦的后端】分享技术干货、读书笔记、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力!

介绍

首先介绍一下 gin-api-mono 这个项目,这个项目是由 go-gin-api 作者基于用户的需求衍生出来的一个项目。因为有些用户觉得 go-gin-api 是一个前后端都有的一个开源项目,对于很多用户来说,前端部分是不需要的,所以作者看到这层需求,从而将后端代码抽离出来成为 gin-api-mono 这个项目。

目前 gin-api-mono 是闭源的,需要的同学可以扫文末二维码购买小册进群交流。

运行

现在我们基于 gin-api-mono 的 README.md 来进行一个 Quick Start:

  • 首先我们创建一个 mysql database 以及一些表结构、数据等。
sql 复制代码
-- 1. 创建数据库 --
CREATE database gin_api_mono;
USE gin_api_mono;

-- 2. 创建数据表 --
CREATE TABLE `admin` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `username` varchar(32) NOT NULL DEFAULT '' COMMENT '用户名',
  `mobile` varchar(20) NOT NULL DEFAULT '' COMMENT '手机号',
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='管理员表';

-- 3. 初始化数据 --
INSERT INTO `admin` (`id`, `username`, `mobile`) VALUES
(1, '张三', '13888888888'),
(2, '李四', '13888888888'),
(3, '赵五', '13888888888');
  • 在 dev 配置中配置上以下信息:
ini 复制代码
[mysql.read]
addr = '127.0.0.1:3306'
name = 'gin_api_mono'
pass = '123456'
user = 'root'

[mysql.write]
addr = '127.0.0.1:3306'
name = 'gin_api_mono'
pass = '123456'
user = 'root'
  • 到此为止,我们已经成功配置好 gin-api-mono 的项目配置了,现在我们开始执行程序:
shell 复制代码
go run main.go -env dev

输出如下即成功:

shell 复制代码
 ██████╗ ██╗███╗   ██╗       █████╗ ██████╗ ██╗      ███╗   ███╗ ██████╗ ███╗   ██╗ ██████╗ 
██╔════╝ ██║████╗  ██║      ██╔══██╗██╔══██╗██║      ████╗ ████║██╔═══██╗████╗  ██║██╔═══██╗
██║  ███╗██║██╔██╗ ██║█████╗███████║██████╔╝██║█████╗██╔████╔██║██║   ██║██╔██╗ ██║██║   ██║
██║   ██║██║██║╚██╗██║╚════╝██╔══██║██╔═══╝ ██║╚════╝██║╚██╔╝██║██║   ██║██║╚██╗██║██║   ██║
╚██████╔╝██║██║ ╚████║      ██║  ██║██║     ██║      ██║ ╚═╝ ██║╚██████╔╝██║ ╚████║╚██████╔╝
 ╚═════╝ ╚═╝╚═╝  ╚═══╝      ╚═╝  ╚═╝╚═╝     ╚═╝      ╚═╝     ╚═╝ ╚═════╝ ╚═╝  ╚═══╝ ╚═════╝

我们来看看对应的 swagger 文档: 我们使用 postman 调用一下接口看看: 目前来看,都是非常顺畅且快速。这对新手来说是非常友好的一个开始,有了正反馈,才会有继续下去的动力。

下面我们快速写一个 TODO List 的 DEMO 看看,检验一下该项目是否能达到快速开发的目标。

TODO List

数据库

首先我们还是先配置好我们的数据结构,简单处理,用户我们就用上面的管理员来表示,简单创建一个 todo 表:

sql 复制代码
CREATE TABLE `todo` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
    `user_id` int(11) NOT NULL COMMENT '用户ID',
    `title` varchar(32) NOT NULL COMMENT '标题',
    `desc` varchar(128) NOT NULL DEFAULT '' COMMENT '描述',
    `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

路由

我们先简单的定义两个简单的路由:

  • POST /api/todo: 创建一个 todo。
  • POST /api/todo/update: 修改某个 todo。

编写对应的 router:

go 复制代码
	todoHandler := todo.New(logger, db)
	todoRouter := mux.Group("/api")
	{
		// 创建一个 todo
		todoRouter.POST("/todo", todoHandler.Create())
		// 修改某个 todo
		todoRouter.POST("/todo/update", todoHandler.Update())
	}

服务

现在我们来编写对应的 handler func。

go 复制代码
var _ Handler = (*handler)(nil)

type Handler interface {
	i()

	// Create 创建一个 todo
	// @Tags API.todo
	// @Router /api/todo [post]
	Create() core.HandlerFunc

	// Update 修改某个 todo
	// @Tags API.todo
	// @Router /api/todo/{id} [post]
	Update() core.HandlerFunc
}

type handler struct {
	logger *zap.Logger
	db     mysql.Repo
}

func New(logger *zap.Logger, db mysql.Repo) Handler {
	return &handler{
		logger: logger,
		db:     db,
	}
}

func (h *handler) i() {}

进而实现对应的接口方法,下面只贴出部分代码:

go 复制代码
// Create 创建一个 todo
// @Summary 创建一个 todo
// @Description 创建一个 todo
// @Tags API.todo
// @Accept json
// @Produce json
// @Param todo body createRequest true "TODO信息"
// @Success 200 {object} createResponse
// @Failure 400 {object} code.Failure
// @Router /api/todo [post]
func (h *handler) Create() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(createRequest)
		res := new(createResponse)
		if err := ctx.ShouldBindJSON(req); err != nil {
			ctx.AbortWithError(core.Error(
				http.StatusBadRequest,
				code.ParamBindError,
				validation.Error(err)).WithError(err),
			)
			return
		}
		// found admin
		a := new(models.Admin)
		adminResult := h.db.GetDbR().WithContext(ctx.RequestContext()).First(&a, req.UserID)
		if adminResult.Error != nil {
			ctx.AbortWithError(core.Error(
				http.StatusBadRequest,
				code.TodoCreateError,
				code.Text(code.TodoCreateError)).WithError(adminResult.Error),
			)
			return
		}
		if a == nil {
			ctx.AbortWithError(core.Error(
				http.StatusBadRequest,
				code.AdminNotFound,
				code.Text(code.AdminNotFound)),
			)
			return
		}

		createData := new(models.Todo)
		createData.UserID = req.UserID
		createData.Title = req.Title
		createData.Desc = req.Desc
		dbResult := h.db.GetDbW().WithContext(ctx.RequestContext()).Create(createData)
		if dbResult.Error != nil {
			ctx.AbortWithError(core.Error(
				http.StatusBadRequest,
				code.TodoCreateError,
				code.Text(code.TodoCreateError)).WithError(dbResult.Error),
			)
			return
		}
		res.Id = createData.Id
		ctx.Payload(res)
	}
}

这样我们就编写好我们的 api 服务了,现在来稍微测试一下创建一个 todo,还是像上面一样,使用 postman 发出一个请求:

总结

从上面的一个简单的例子来看,进行一些简单的 CURL api 的编写还是非常快速的,可以使用这个框架进行快速开发,从而将产品快速推出市场进行验证。目前从简单的测试来看,应该对新人还是非常友好的,屏蔽了一些底层细节,专注在上层服务的编写,没有过高的心智负担。大家感兴趣的话,可以扫码进群交流。

相关推荐
猪猪拆迁队1 小时前
虚拟工厂仿真引擎的架构设计:让一条产线可编程、可观测、可干预
后端·ai编程
字节跳动数据库1 小时前
文章分享——相似函数处理方法
人工智能·后端·程序员
云技纵横1 小时前
@Transactional 失效的 7 种场景:第 5 种最难排查
后端
用户6757049885022 小时前
你知道 Go 结构体和结构体指针调用的区别吗?一文带你彻底搞懂!
后端·go
程序员cxuan2 小时前
读懂 Claude Code 架构分析系列,第一篇,开始!
人工智能·后端·架构
用户6757049885022 小时前
面试官问“装饰器模式”,这样回答薪资多要 3000!
后端
tntxia2 小时前
Geo Scene域名修改引起的一些问题
后端
用户298698530142 小时前
Java 实现 Word 文档加密与权限解除
java·后端
vanuan2 小时前
给你的A2A-Agent加把锁-认证鉴权实战指南
后端
Yeats_Liao3 小时前
14:Servlet中的页面跳转-Java Web
java·后端·架构