Gen Web - 基于 Gin 框架封装的脚手架结构,便于快速开发 API
介绍
主要使用以下开源组件:
项目目录结构清晰明了,简单易用,快速上手,包含了一个用户注册、登录、文章增删改查等功能的 Restful API 应用,仅供参考!
主要包含以下 API:
METHOD | URI | DESCRIPTION |
---|---|---|
GET | / | 默认首页 |
POST | /api/v1/user/register | 用户注册 |
POST | /api/v1/user/login | 用户登录 |
POST | /api/v1/user/logout | 用户登出 |
GET | /api/v1/articles | 文章列表 |
POST | /api/v1/articles | 发布文章 |
GET | /api/v1/articles/:id | 文章详情 |
PUT | /api/v1/articles/:id | 修改文章 |
DELETE | /api/v1/articles/:id | 删除文章 |
POST | /api/v1/articles/:id/comments | 添加文章评论 |
架构
Service
type ArticleService struct {
SQLStore *SQLService `inject:""`
Cache *cache.CacheService `inject:""`
}
func init() {
registry.RegisterService(&ArticleService{})
}
func (r ArticleService) Init() error {
return nil
}
既灵活,也不影响性能,因为虽然依赖注入使用了反射,但是我们只在程序启动之前做这件事,而且只需要进行一次。
启动流程
mainapp.ini
Server
// Server is responsible for managing the lifecycle of services.
type Server struct {
context context.Context
shutdownFn context.CancelFunc
childRoutines *errgroup.Group
log *zap.Logger
cfg *config.Cfg // 项目配置
shutdownOnce sync.Once
shutdownFinished chan struct{}
isInitialized bool
mtx sync.Mutex
serviceRegistry serviceRegistry // 注册的服务
}
zap/zap_logger.go
Init
RunHTTPServer
type HTTPServer struct {
log *zap.Logger
gin *gin.Engine
context context.Context
Cfg *config.Cfg `inject:""`
ArticleService *article.ArticleService `inject:""`
UserService *user.UserService `inject:""`
}
api/http_server.go
代码介绍
services
项目整体是一个 3 层架构,即控制器层、Service 层、模型层。
个人理解,控制器层主要做一些接口参数校验等工作,模型层主要是数据操作,Service 层才是主要的业务逻辑。
models/db.go
type SQLService struct {
Cfg *config.Cfg `inject:""`
conns map[string]*gorm.DB
log *zap.Logger
}
func DB(dbName ...string) *gorm.DB {
if len(dbName) > 0 {
if conn, ok := sqlStore.conns[dbName[0]]; ok {
return conn
}
}
return db
}
项目使用了 Gorm ( 2.0 版本),具体详细用法可以参考官方文档。
api/api.gomiddleware
config/config.go
go-playground/validator/v10
type CreateArticleCommand struct {
Id int
UserId int
Title string `form:"title" json:"title" binding:"gt=1,lt=100"`
Content string `form:"content" json:"content" binding:"gt=1,lt=2000"`
}
type UpdateArticleCommand struct {
Id int
UserId int
Title string `form:"title" json:"title" binding:"gt=1,lt=100"`
Content string `form:"content" json:"content" binding:"gt=1,lt=2000"`
}
。。。 。。。 。。。