Gen Web - 基于 Gin 框架封装的脚手架结构,便于快速开发 API

介绍

主要使用以下开源组件:

项目目录结构清晰明了,简单易用,快速上手,包含了一个用户注册、登录、文章增删改查等功能的 Restful API 应用,仅供参考!

主要包含以下 API:

METHODURIDESCRIPTION
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"`
}

。。。 。。。 。。。