openapi

package
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 2, 2026 License: MIT Imports: 8 Imported by: 0

README

openapi 包 — OpenAPI 文档生成

所属层级: Infrastructure Layer
设计理念: 自动生成,OpenAPI 3.0 规范
设计灵感: Spring Boot springdoc-openapi

概述

openapi 包提供 OpenAPI/Swagger 文档自动生成功能,参考 Spring Boot 的 springdoc-openapi 设计。自动从代码注解和路由信息生成 OpenAPI 3.0 规范的文档。

核心功能
功能 说明
自动生成 从代码注解和路由信息自动生成文档
OpenAPI 3.0 支持 OpenAPI 3.0 规范
JSON/YAML 支持生成 JSON 和 YAML 格式文档
Swagger UI 提供 Swagger UI 端点
控制器注册 支持从控制器自动提取 API 信息

核心接口

OpenAPIDocument OpenAPI 文档
type OpenAPIDocument struct {
    OpenAPI    string
    Info       InfoObject
    Servers    []ServerObject
    Paths      map[string]PathItem
    Components *ComponentsObject
    Tags       []TagObject
}
创建
doc := openapi.NewDocument()
设置文档信息
doc.SetInfo("My API", "1.0.0", "A sample API")
doc.SetServer("http://localhost:8080", "Development server")
注册控制器
doc.RegisterController(&UserController{})
doc.RegisterController(&OrderController{})
生成文档
// 生成 JSON 格式文档
json, err := doc.ToJSON()

// 生成 YAML 格式文档
yaml, err := doc.ToYAML()
InfoObject 文档信息
type InfoObject struct {
    Title          string
    Version        string
    Description    string
    TermsOfService string
    Contact        *ContactObject
    License        *LicenseObject
}
ServerObject 服务器信息
type ServerObject struct {
    URL         string
    Description string
    Variables   map[string]ServerVariable
}
PathItem 路径项
type PathItem struct {
    Summary     string
    Description string
    Get         *OperationObject
    Post        *OperationObject
    Put         *OperationObject
    Delete      *OperationObject
    Patch       *OperationObject
    Parameters  []ParameterObject
    Tags        []string
}
OperationObject 操作对象
type OperationObject struct {
    Summary     string
    Description string
    OperationID string
    Tags        []string
    Parameters  []ParameterObject
    RequestBody *RequestBodyObject
    Responses   map[string]ResponseObject
}

快速开始

基本使用
package main

import (
    "fmt"
    "github.com/xudefa/enhance/openapi"
)

func main() {
    // 创建文档
    doc := openapi.NewDocument()
    doc.SetInfo("My API", "1.0.0", "A sample API")
    doc.SetServer("http://localhost:8080", "Development server")

    // 注册控制器
    doc.RegisterController(&UserController{})

    // 生成 JSON
    json, err := doc.ToJSON()
    if err != nil {
        panic(err)
    }
    fmt.Println(string(json))
}

API 参考

提供 Swagger UI
func main() {
    doc := openapi.NewDocument()
    doc.SetInfo("My API", "1.0.0", "A sample API")
    doc.SetServer("http://localhost:8080", "Development server")

    doc.RegisterController(&UserController{})
    doc.RegisterController(&OrderController{})

    // 提供 Swagger UI
    openapi.ServeSwaggerUI(doc, "/swagger", 8080)
}
添加标签
doc := openapi.NewDocument()

// 添加标签
doc.AddTag("user", "User management APIs")
doc.AddTag("order", "Order management APIs")

// 注册控制器时指定标签
doc.RegisterController(&UserController{})
添加安全方案
doc := openapi.NewDocument()

// 添加 Bearer Token 认证
doc.AddSecurityScheme("BearerAuth", openapi.SecurityScheme{
    Type:         "http",
    Scheme:       "bearer",
    BearerFormat: "JWT",
    Description:  "JWT Bearer token authentication",
})

// 设置为全局安全要求
doc.SetSecurityRequirement("BearerAuth", []string{})

使用示例

场景 1: API 文档自动生成

从代码自动生成 API 文档,保持文档与代码同步:

func main() {
    doc := openapi.NewDocument()
    doc.SetInfo("User Service API", "2.0.0", "User management service")
    
    // 添加服务器
    doc.SetServer("https://api.example.com", "Production")
    doc.SetServer("https://staging-api.example.com", "Staging")
    
    // 注册所有控制器
    doc.RegisterController(&UserController{})
    doc.RegisterController(&RoleController{})
    doc.RegisterController(&PermissionController{})
    
    // 保存文档
    json, _ := doc.ToJSON()
    os.WriteFile("openapi.json", json, 0644)
}

最佳实践:

  • 在构建流程中自动生成文档
  • 文档版本与 API 版本保持一致
  • 提供详细的描述信息
场景 2: 开发环境 Swagger UI

开发环境提供交互式 API 文档,方便调试和测试:

func main() {
    doc := buildAPIDocument()
    
    // 仅开发环境启用
    if isDevMode() {
        openapi.ServeSwaggerUI(doc, "/swagger", 8080)
    }
    
    startServer()
}

最佳实践:

  • 仅开发环境启用 Swagger UI
  • 生产环境禁用交互式文档
  • 使用独立的文档端口
场景 3: API 网关集成

生成 OpenAPI 文档供 API 网关使用:

func generateGatewayConfig() {
    doc := openapi.NewDocument()
    doc.SetInfo("Gateway API", "1.0.0", "API Gateway")
    
    // 注册所有后端服务
    doc.RegisterController(&UserService{})
    doc.RegisterController(&OrderService{})
    doc.RegisterController(&PaymentService{})
    
    // 生成 YAML 供网关使用
    yaml, _ := doc.ToYAML()
    os.WriteFile("gateway-config.yaml", yaml, 0644)
}

最佳实践:

  • 使用 YAML 格式便于阅读
  • 包含所有后端服务 API
  • 定期更新网关配置

最佳实践

1. 文档版本管理
// ✅ 推荐:文档版本与 API 版本一致
doc.SetInfo("User Service API", "v2.0.0", "User management service")

// ⚠️ 不推荐:版本不一致
doc.SetInfo("User Service API", "1.0.0", "User management service")
2. 环境隔离
// ✅ 推荐:根据环境配置服务器
if isProduction() {
    doc.SetServer("https://api.example.com", "Production")
} else if isStaging() {
    doc.SetServer("https://staging-api.example.com", "Staging")
} else {
    doc.SetServer("http://localhost:8080", "Development")
}

// ⚠️ 不推荐:硬编码服务器地址
doc.SetServer("http://localhost:8080", "Development server")
3. 安全方案配置
// ✅ 推荐:配置安全方案
doc.AddSecurityScheme("BearerAuth", openapi.SecurityScheme{
    Type:         "http",
    Scheme:       "bearer",
    BearerFormat: "JWT",
    Description:  "JWT Bearer token authentication",
})
doc.SetSecurityRequirement("BearerAuth", []string{})

// ⚠️ 不推荐:不配置安全方案
// 文档中没有认证信息
4. 标签组织
// ✅ 推荐:使用标签组织 API
doc.AddTag("user", "User management APIs")
doc.AddTag("order", "Order management APIs")
doc.AddTag("auth", "Authentication APIs")

// ⚠️ 不推荐:不使用标签
// 所有 API 混在一起,难以查找
5. 与依赖注入集成
// ✅ 推荐:将 OpenAPI 文档注册为 Bean
container.Register(
    reflect.TypeOf(&openapi.OpenAPIDocument{}),
    core.Bean(createOpenAPIDocument()),
    core.Singleton(),
)

// 注入使用
type APIService struct {
    Document *openapi.OpenAPIDocument `inject:"openapiDocument"`
}

func (s *APIService) Start() {
    openapi.ServeSwaggerUI(s.Document, "/swagger", 8080)
}
6. 设计要点
  • 支持 OpenAPI 3.0 规范
  • 从控制器自动提取路由信息
  • 支持 JSON 和 YAML 两种格式
  • 提供 Swagger UI 集成
  • 零外部依赖,仅使用 Go 标准库

Documentation

Overview

Package openapi 提供 OpenAPI 文档生成功能,用于 enhance 框架。

该模块自动从控制器注解生成 OpenAPI 3.0 规范文档,支持 Swagger UI 集成。 参考 SpringDoc OpenAPI 的设计理念。

架构设计

  • OpenAPI: OpenAPI 文档结构,定义 API 规范
  • Operation: 操作定义,描述单个 API 端点
  • Schema: 数据模型定义,描述请求和响应结构
  • SwaggerUI: Swagger UI 集成,提供可视化文档界面

核心功能

  • 文档生成: 自动从代码注解生成 OpenAPI 3.0 文档
  • Swagger UI: 集成 Swagger UI,提供交互式 API 文档
  • 注解支持: 支持 @Operation、@Parameter、@Response 等注解
  • 数据模型: 自动生成请求和响应的数据模型定义

使用方式

在控制器中使用注解:

// @Operation(summary: "Get user by ID")
// @Parameter(name: "id", in: "path", required: true)
// @Response(code: 200, description: "Success")
func GetUser(c *gin.Context) {
    // 处理逻辑
}

启用 Swagger UI:

import _ "github.com/xudefa/enhance/openapi"

访问文档:

浏览器访问: http://localhost:8080/swagger/index.html

配置属性

  • openapi.enabled: 是否启用 OpenAPI 文档(默认 true)
  • openapi.title: API 文档标题
  • openapi.version: API 版本
  • openapi.description: API 描述

配置示例

环境变量:

export OPENAPI_ENABLED=true
export OPENAPI_TITLE="My API"
export OPENAPI_VERSION="1.0.0"

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ServeSwaggerUI

func ServeSwaggerUI(doc *DocumentBuilder, basePath string, port int) error

ServeSwaggerUI 提供 Swagger UI 服务

Types

type APIOperation

type APIOperation struct {
	// Summary 操作摘要
	Summary string
	// Description 操作描述
	Description string
	// OperationID 操作 ID
	OperationID string
	// Tags 标签列表
	Tags []string
	// Deprecated 是否已弃用
	Deprecated bool
}

APIOperation API 操作注解

type APIParam

type APIParam struct {
	// Name 参数名称
	Name string
	// In 参数位置 (query, path, header, cookie)
	In string
	// Description 参数描述
	Description string
	// Required 是否必填
	Required bool
	// Example 示例值
	Example any
}

APIParam API 参数注解

type APIResponse

type APIResponse struct {
	// StatusCode HTTP 状态码
	StatusCode int
	// Description 响应描述
	Description string
	// Type 响应类型
	Type any
}

APIResponse API 响应注解

type APISecurity

type APISecurity struct {
	// Name 安全方案名称
	Name string
	// Scopes 权限范围
	Scopes []string
}

APISecurity API 安全注解

type APITag

type APITag struct {
	// Name 标签名称
	Name string
	// Description 标签描述
	Description string
}

APITag API 标签注解

type ComponentsObject

type ComponentsObject struct {
	Schemas         map[string]SchemaObject         `json:"schemas,omitempty"`
	Responses       map[string]ResponseObject       `json:"responses,omitempty"`
	Parameters      map[string]ParameterObject      `json:"parameters,omitempty"`
	RequestBodies   map[string]RequestBodyObject    `json:"requestBodies,omitempty"`
	SecuritySchemes map[string]SecuritySchemeObject `json:"securitySchemes,omitempty"`
}

ComponentsObject 组件对象

type ContactObject

type ContactObject struct {
	Name  string `json:"name,omitempty"`
	URL   string `json:"url,omitempty"`
	Email string `json:"email,omitempty"`
}

ContactObject 联系信息

type DocumentBuilder

type DocumentBuilder struct {
	// contains filtered or unexported fields
}

DocumentBuilder 文档构建器

func NewDocument

func NewDocument() *DocumentBuilder

NewDocument 创建新的 OpenAPI 文档

func (*DocumentBuilder) AddPath

func (b *DocumentBuilder) AddPath(path string, method string, operation OperationObject) *DocumentBuilder

AddPath 手动添加路径

func (*DocumentBuilder) AddSchema

func (b *DocumentBuilder) AddSchema(name string, schema SchemaObject) *DocumentBuilder

AddSchema 添加 Schema

func (*DocumentBuilder) AddSecurityScheme

func (b *DocumentBuilder) AddSecurityScheme(name string, scheme SecuritySchemeObject) *DocumentBuilder

AddSecurityScheme 添加安全方案

func (*DocumentBuilder) AddServer

func (b *DocumentBuilder) AddServer(url, description string) *DocumentBuilder

AddServer 添加服务器

func (*DocumentBuilder) AddTag

func (b *DocumentBuilder) AddTag(name, description string) *DocumentBuilder

AddTag 添加标签

func (*DocumentBuilder) Build

func (b *DocumentBuilder) Build() *OpenAPIDocument

Build 构建文档

func (*DocumentBuilder) RegisterController

func (b *DocumentBuilder) RegisterController(controller any) *DocumentBuilder

RegisterController 注册控制器

func (*DocumentBuilder) RegisterSchema

func (b *DocumentBuilder) RegisterSchema(name string, typ reflect.Type) *DocumentBuilder

RegisterSchema 注册结构体 Schema

func (*DocumentBuilder) SaveToFile

func (b *DocumentBuilder) SaveToFile(path string) error

SaveToFile 保存到文件

func (*DocumentBuilder) ServeHTTP

func (b *DocumentBuilder) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP 实现 http.Handler,提供 OpenAPI JSON 端点

func (*DocumentBuilder) SetContact

func (b *DocumentBuilder) SetContact(name, url, email string) *DocumentBuilder

SetContact 设置联系信息

func (*DocumentBuilder) SetInfo

func (b *DocumentBuilder) SetInfo(title, version, description string) *DocumentBuilder

SetInfo 设置文档信息

func (*DocumentBuilder) SetLicense

func (b *DocumentBuilder) SetLicense(name, url string) *DocumentBuilder

SetLicense 设置许可证信息

func (*DocumentBuilder) SetTermsOfService

func (b *DocumentBuilder) SetTermsOfService(terms string) *DocumentBuilder

SetTermsOfService 设置服务条款

func (*DocumentBuilder) ToJSON

func (b *DocumentBuilder) ToJSON() (string, error)

ToJSON 转换为 JSON

func (*DocumentBuilder) ToJSONBytes

func (b *DocumentBuilder) ToJSONBytes() ([]byte, error)

ToJSONBytes 转换为 JSON 字节

type ExampleObject

type ExampleObject struct {
	Summary       string `json:"summary,omitempty"`
	Description   string `json:"description,omitempty"`
	Value         any    `json:"value,omitempty"`
	ExternalValue string `json:"externalValue,omitempty"`
}

ExampleObject 示例对象

type HeaderObject

type HeaderObject struct {
	Description string        `json:"description,omitempty"`
	Schema      *SchemaObject `json:"schema,omitempty"`
}

HeaderObject 头部对象

type InfoObject

type InfoObject struct {
	Title          string         `json:"title"`
	Version        string         `json:"version"`
	Description    string         `json:"description,omitempty"`
	TermsOfService string         `json:"termsOfService,omitempty"`
	Contact        *ContactObject `json:"contact,omitempty"`
	License        *LicenseObject `json:"license,omitempty"`
}

InfoObject 文档信息

type LicenseObject

type LicenseObject struct {
	Name string `json:"name"`
	URL  string `json:"url,omitempty"`
}

LicenseObject 许可证信息

type LinkObject

type LinkObject struct {
	OperationRef string            `json:"operationRef,omitempty"`
	OperationID  string            `json:"operationId,omitempty"`
	Parameters   map[string]string `json:"parameters,omitempty"`
}

LinkObject 链接对象

type MediaTypeObject

type MediaTypeObject struct {
	Schema   *SchemaObject            `json:"schema,omitempty"`
	Example  any                      `json:"example,omitempty"`
	Examples map[string]ExampleObject `json:"examples,omitempty"`
}

MediaTypeObject 媒体类型对象

type OAuthFlowObject

type OAuthFlowObject struct {
	AuthorizationURL string            `json:"authorizationUrl,omitempty"`
	TokenURL         string            `json:"tokenUrl,omitempty"`
	RefreshURL       string            `json:"refreshUrl,omitempty"`
	Scopes           map[string]string `json:"scopes"`
}

OAuthFlowObject OAuth 流程对象

type OAuthFlowsObject

type OAuthFlowsObject struct {
	Implicit          *OAuthFlowObject `json:"implicit,omitempty"`
	Password          *OAuthFlowObject `json:"password,omitempty"`
	ClientCredentials *OAuthFlowObject `json:"clientCredentials,omitempty"`
	AuthorizationCode *OAuthFlowObject `json:"authorizationCode,omitempty"`
}

OAuthFlowsObject OAuth 流程对象

type OpenAPIDocument

type OpenAPIDocument struct {
	OpenAPI    string              `json:"openapi"`
	Info       InfoObject          `json:"info"`
	Servers    []ServerObject      `json:"servers,omitempty"`
	Paths      map[string]PathItem `json:"paths"`
	Components *ComponentsObject   `json:"components,omitempty"`
	Tags       []TagObject         `json:"tags,omitempty"`
}

OpenAPIDocument OpenAPI 3.0 文档

type OperationObject

type OperationObject struct {
	Summary     string                    `json:"summary,omitempty"`
	Description string                    `json:"description,omitempty"`
	OperationID string                    `json:"operationId,omitempty"`
	Tags        []string                  `json:"tags,omitempty"`
	Parameters  []ParameterObject         `json:"parameters,omitempty"`
	RequestBody *RequestBodyObject        `json:"requestBody,omitempty"`
	Responses   map[string]ResponseObject `json:"responses"`
	Deprecated  bool                      `json:"deprecated,omitempty"`
	Security    []map[string][]string     `json:"security,omitempty"`
}

OperationObject 操作对象

type ParameterObject

type ParameterObject struct {
	Name        string        `json:"name"`
	In          string        `json:"in"` // query, path, header, cookie
	Description string        `json:"description,omitempty"`
	Required    bool          `json:"required,omitempty"`
	Schema      *SchemaObject `json:"schema,omitempty"`
	Example     any           `json:"example,omitempty"`
}

ParameterObject 参数对象

type PathItem

type PathItem struct {
	Summary     string            `json:"summary,omitempty"`
	Description string            `json:"description,omitempty"`
	Get         *OperationObject  `json:"get,omitempty"`
	Post        *OperationObject  `json:"post,omitempty"`
	Put         *OperationObject  `json:"put,omitempty"`
	Delete      *OperationObject  `json:"delete,omitempty"`
	Patch       *OperationObject  `json:"patch,omitempty"`
	Parameters  []ParameterObject `json:"parameters,omitempty"`
	Tags        []string          `json:"tags,omitempty"`
}

PathItem 路径项

type RequestBodyObject

type RequestBodyObject struct {
	Description string                     `json:"description,omitempty"`
	Required    bool                       `json:"required,omitempty"`
	Content     map[string]MediaTypeObject `json:"content"`
}

RequestBodyObject 请求体对象

type ResponseObject

type ResponseObject struct {
	Description string                     `json:"description"`
	Headers     map[string]HeaderObject    `json:"headers,omitempty"`
	Content     map[string]MediaTypeObject `json:"content,omitempty"`
	Links       map[string]LinkObject      `json:"links,omitempty"`
}

ResponseObject 响应对象

type SchemaObject

type SchemaObject struct {
	Type                 string                  `json:"type,omitempty"`
	Format               string                  `json:"format,omitempty"`
	Description          string                  `json:"description,omitempty"`
	Properties           map[string]SchemaObject `json:"properties,omitempty"`
	Required             []string                `json:"required,omitempty"`
	Items                *SchemaObject           `json:"items,omitempty"`
	AdditionalProperties *SchemaObject           `json:"additionalProperties,omitempty"`
	Enum                 []string                `json:"enum,omitempty"`
	Default              any                     `json:"default,omitempty"`
	Example              any                     `json:"example,omitempty"`
	Minimum              *float64                `json:"minimum,omitempty"`
	Maximum              *float64                `json:"maximum,omitempty"`
	MinLength            *int                    `json:"minLength,omitempty"`
	MaxLength            *int                    `json:"maxLength,omitempty"`
	Pattern              string                  `json:"pattern,omitempty"`
	Nullable             bool                    `json:"nullable,omitempty"`
	ReadOnly             bool                    `json:"readOnly,omitempty"`
	WriteOnly            bool                    `json:"writeOnly,omitempty"`
}

SchemaObject Schema 对象

type SecuritySchemeObject

type SecuritySchemeObject struct {
	Type             string            `json:"type"`
	Description      string            `json:"description,omitempty"`
	Name             string            `json:"name,omitempty"`
	In               string            `json:"in,omitempty"`
	Scheme           string            `json:"scheme,omitempty"`
	BearerFormat     string            `json:"bearerFormat,omitempty"`
	Flows            *OAuthFlowsObject `json:"flows,omitempty"`
	OpenIDConnectURL string            `json:"openIdConnectUrl,omitempty"`
}

SecuritySchemeObject 安全方案对象

type ServerObject

type ServerObject struct {
	URL         string                    `json:"url"`
	Description string                    `json:"description,omitempty"`
	Variables   map[string]ServerVariable `json:"variables,omitempty"`
}

ServerObject 服务器信息

type ServerVariable

type ServerVariable struct {
	Default     string   `json:"default"`
	Description string   `json:"description,omitempty"`
	Enum        []string `json:"enum,omitempty"`
}

ServerVariable 服务器变量

type TagObject

type TagObject struct {
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
}

TagObject 标签对象

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL