规范路由与 OpenAPI 自动接口文档
从 v2 开始官方主推“规范路由”:请求/响应结构体本身就是接口定义,路由地址与请求方法写在 g.Meta 标签里,Server 据此自动生成标准 OpenAPIv3 接口文档,并内置 Swagger UI 页面。本章先查证清楚再动手:官方对“规范路由 + OpenAPI 自动文档”是完整支持且为框架一等特性。
基本概念
- 路由方法固定签名:
func Handler(ctx context.Context, req *XxxReq) (res *XxxRes, err error),四个组成部分缺一不可。 - 入参结构体嵌入
g.Meta,用标签声明path、method、tags、summary(缩写sm)、dc(描述)等。 - 接口文档与 Swagger 默认关闭,由配置项开启。
开启文档并注册路由
server:
address: ":8199"
openapiPath: "/api.json" # OpenAPIv3 文档地址
swaggerPath: "/swagger" # Swagger UI 地址
package main
import (
"context"
"fmt"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
type HelloReq struct {
g.Meta `path:"/hello" method:"get" tags:"Hello" summary:"say hello"`
Name string `v:"required" dc:"your name"`
}
type HelloRes struct {
Reply string `dc:"reply content"`
}
type Hello struct{}
func (Hello) Say(ctx context.Context, req *HelloReq) (res *HelloRes, err error) {
res = &HelloRes{Reply: fmt.Sprintf("Hi %s", req.Name)}
return
}
func main() {
s := g.Server()
s.Use(ghttp.MiddlewareHandlerResponse) // 统一 {code,message,data} 返回
s.Group("/", func(group *ghttp.RouterGroup) {
group.Bind(new(Hello))
})
s.Run()
}
启动后:GET /hello?name=john 返回统一格式数据;/api.json 返回自动生成的 OpenAPIv3 文档;/swagger 打开 Swagger UI。注册路由时日志会列出框架自动注册的 /api.json 与 /swagger/* 两个内部路由。
结构体即接口文档
生成的文档无需手写:Server 根据 g.Meta 标签与字段信息自动推导出 paths、parameters、responses 与 schemas。官方还说明,goai 组件能把结构体字段上的数据校验规则自动转成 OpenAPI 约束:required → required: true,between:18,60 → minimum/maximum,in:admin,user → enum,length 系列 → minLength/maxLength。这让“文档不落后于校验代码”成为可能。
自定义补充:s.GetOpenApi() 可拿到文档对象手动完善全局信息(如公共响应包一层 code/message/data);响应结构体实现 IEnhanceResponseStatus 接口可为不同 HTTP 状态码补充响应示例。
注意点
- 规范路由入参结构体即使没有参数也必须定义,因为它同时承载接口定义。
- 请求对象进入处理器前会自动校验,内置
bail修饰(失败即停);含required*规则时建议把它放最前,避免被提前中断的校验“吞掉”。 - 想要自定义统一返回时,后置中间件通过
r.GetHandlerResponse()拿业务结果再包装。 - 文档地址默认关闭,线上如不希望文档公开,可用钩子给
/api.json加 BasicAuth 之类的鉴权。
小结
规范路由把“写接口”收敛成“写结构体”,OpenAPI/Swagger 属于自动产物而非额外维护项。配合校验规则自动转换,接口文档、入参校验与代码可以做到同源一致,是 v2 项目应优先采用的路由形态。支持程度与更多标签以官方文档 goframe.org 为准。