实战三:企业级 API 骨架

最后把前面所有能力串成一张“可复制的新项目骨架”:规范目录、统一响应、鉴权、日志、数据库、Redis、优雅退出一次配齐。每个零件前面章节都讲过,本章重在“串”与“顺序”。

目录结构(官方工程规范)

project/
├── api/                      # Req/Res 接口定义(规范路由)
├── hack/config.yaml          # gf-cli 生成配置(gen dao 等)
├── manifest/config/config.yaml # 运行时配置
├── internal/
│   ├── cmd/ controller/ service/ logic/ dao/ model/ middleware/
└── main.go

internal 内部分层职责见“工程目录与代码生成”相关章节:controller 接线、logic 实现业务、dao/model 为生成物、middleware 放通用中间件。

配置文件

server:
  address: ":8000"
  openapiPath: "/api.json"
  swaggerPath: "/swagger"
database:
  default:
    link: "mysql:root:12345678@tcp(127.0.0.1:3306)/demo?loc=Local&parseTime=true"
    debug: false
    maxIdle: 10
    maxOpen: 100
redis:
  default:
    address: "127.0.0.1:6379"
    db: 0

中间件链与启动命令

package middleware
import "github.com/gogf/gf/v2/net/ghttp"

func Register() []ghttp.HandlerFunc {
	return []ghttp.HandlerFunc{
		ghttp.MiddlewareHandlerResponse, // 1 统一响应(最外,业务只 return res, err)
		MiddlewareCORS,                  // 2 跨域(在鉴权前,别误杀 OPTIONS 预检)
		MiddlewareAuth,                  // 3 鉴权(内置白名单,如 /login、/swagger)
		MiddlewareAccessLog,             // 4 访问日志(计时;ctx 带链路信息则含 TraceId)
	}
}
package cmd

import (
	"context"
	"os"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gcmd"
	"github.com/gogf/gf/v2/os/gproc"
	"project/internal/controller/article"
	"project/internal/middleware"
	_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
	_ "github.com/gogf/gf/contrib/nosql/redis/v2"
)

var Main = &gcmd.Command{
	Name:  "main",
	Brief: "start http server",
	Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
		s := g.Server()
		s.Use(middleware.Register()...)
		s.Group("/api", func(group *ghttp.RouterGroup) {
			group.Bind(new(article.Controller))
		})
		gproc.AddSigHandlerShutdown(func(sig os.Signal) { _ = s.Shutdown() }) // 优雅退出
		s.Run()
		return
	},
}

main.go 只需 import _ "project/internal/cmd"(init 完成注册)后执行 gcmd.Run(gctx.New())(见命令行章节)。

一次请求的旅程

请求经 Nginx 反代到达 ghttp.Server → 中间件链(统一响应 → CORS → 鉴权注入 uid → 访问日志计时)→ 规范路由按 g.Meta 匹配 handler,v 标签自动校验 → controller 调 logic → logic 用 dao.Xxx.Ctx(ctx) 操作 MySQL、g.Redis() 读写缓存,全程携带 ctx 使 ORM/Redis/日志挂上链路 → 返回 res, err 由统一响应输出 {code,message,data},出错按 gerror 错误码收敛并记录日志 → 收到 SIGTERM 时优雅退出回调执行 s.Shutdown(),存量请求处理完再退出。

扩展清单

  • 新增模块:复制 api/xxx/v1 + controller + logic,或用 gf gen ctrl/service 提速;定时任务在启动命令里 gcron.Add;链路追踪在启动时初始化 OTLP 上报器,部署走静态编译 + Nginx/supervisor/Docker。
  • 中间件顺序即执行顺序,新增时明确“放最外还是最内”;驱动包必须空导入注册,漏了会报 “database type not found”。
  • 配置、密钥、时区在骨架搭建时就定好规范,后续模块按同一约定扩展。

小结

企业级骨架 = 规范目录 + 全局中间件链 + gcmd 启动命令 + 优雅退出。零件就绪后,剩下的就是按业务往 api/logic 填模块;每一环更细的官方能力均可回查 goframe.org 对应章节。

笔记加载中…