golang高效生成OpenAPI 3规范的Web框架插件Fuego的使用
Golang高效生成OpenAPI 3规范的Web框架插件Fuego的使用
Fuego是一个为忙碌的Go开发者设计的框架,它能自动从代码生成OpenAPI 3规范文档,而无需依赖注释或YAML文件。
主要特性
- 自动生成OpenAPI文档:直接从代码生成,无需额外注释
- 100%兼容net/http:可以无缝使用任何http.Handler中间件
- 内置路由:基于Go 1.22 net/http的路由系统
- 自动序列化/反序列化:支持JSON、XML和HTML表单
- 内置验证:基于go-playground/validator的验证系统
- 数据转换:通过InTransform和OutTransform接口实现
- 中间件支持:兼容标准net/http中间件
- 错误处理:遵循RFC 9457标准
- 渲染支持:内置html/template支持
快速入门示例
Hello World示例
package main
import "github.com/go-fuego/fuego"
func main() {
s := fuego.NewServer()
fuego.Get(s, "/", func(c fuego.ContextNoBody) (string, error) {
return "Hello, World!", nil
})
s.Run()
}
简单POST请求示例
package main
import "github.com/go-fuego/fuego"
type MyInput struct {
Name string `json:"name" validate:"required"`
}
type MyOutput struct {
Message string `json:"message"`
}
func main() {
s := fuego.NewServer()
// 自动为这个路由生成OpenAPI文档
fuego.Post(s, "/user/{user}", myController)
s.Run()
}
func myController(c fuego.ContextWithBody[MyInput]) (*MyOutput, error) {
body, err := c.Body()
if err != nil {
return nil, err
}
return &MyOutput{Message: "Hello, " + body.Name}, nil
}
数据转换和自定义验证
type MyInput struct {
Name string `json:"name" validate:"required"`
}
// 在返回c.Body()之前调用
func (r *MyInput) InTransform(context.Context) error {
r.Name = strings.ToLower(r.Name)
if r.Name == "fuego" {
return errors.New("fuego is not a valid name for this input")
}
return nil
}
完整OpenAPI文档示例
package main
import (
"github.com/go-fuego/fuego"
"github.com/go-fuego/fuego/option"
"github.com/go/fuego/param"
)
func main() {
s := fuego.NewServer()
// 自定义OpenAPI选项
fuego.Post(s, "/", myController,
option.Description("This route does something..."),
option.Summary("This is my summary"),
option.Tags("MyTag"), // 根据返回类型自动设置标签(可禁用)
option.Deprecated(), // 在OpenAPI规范中标记为弃用
option.Query("name", "Declares a query parameter with default value", param.Default("Carmack")),
option.Header("Authorization", "Bearer token", param.Required()),
optionPagination,
optionCustomBehavior,
)
s.Run()
}
var optionPagination = option.Group(
option.QueryInt("page", "Page number", param.Default(1), param.Example("1st page", 1), param.Example("42nd page", 42)),
option.QueryInt("perPage", "Number of items per page"),
)
var optionCustomBehavior = func(r *fuego.BaseRoute) {
r.XXX = "YYY"
}
标准库兼容示例
package main
import (
"net/http"
"github.com/go-fuego/fuego"
)
func main() {
s := fuego.NewServer()
// 标准net/http中间件
fuego.Use(s, func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Hello", "World")
next.ServeHTTP(w, r)
})
})
// 标准net/http处理器,自动生成OpenAPI路由声明
fuego.GetStd(s, "/std", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
})
s.Run()
}
完整示例
package main
import (
"context"
"errors"
"net/http"
"strings"
chiMiddleware "github.com/go-chi/chi/v5/middleware"
"github.com/go-fuego/fuego"
"github.com/rs/cors"
)
type Received struct {
Name string `json:"name" validate:"required"`
}
type MyResponse struct {
Message string `json:"message"`
BestFramework string `json:"best"`
}
func main() {
s := fuego.NewServer(
fuego.WithAddr("localhost:8088"),
)
fuego.Use(s, cors.Default().Handler)
fuego.Use(s, chiMiddleware.Compress(5, "text/html", "text/css"))
// Fuego处理器,自动生成OpenAPI、验证、(反)序列化和错误处理
fuego.Post(s, "/", func(c fuego.ContextWithBody[Received]) (MyResponse, error) {
data, err := c.Body()
if err != nil {
return MyResponse{}, err
}
c.Response().Header().Set("X-Hello", "World")
return MyResponse{
Message: "Hello, " + data.Name,
BestFramework: "Fuego!",
}, nil
})
// 标准net/http处理器,自动生成OpenAPI路由声明
fuego.GetStd(s, "/std", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
})
s.Run()
}
// 在使用c.Body()时调用InTransform
// 可用于转换实体和引发自定义错误
func (r *Received) InTransform(context.Context) error {
r.Name = strings.ToLower(r.Name)
if r.Name == "fuego" {
return errors.New("fuego is not a name")
}
return nil
}
// 在发送数据前调用OutTransform
func (r *MyResponse) OutTransform(context.Context) error {
r.Message = strings.ToUpper(r.Message)
return nil
}
使用Fuego的优势
- 从代码自动生成OpenAPI文档,无需维护额外文件
- 内置数据验证和转换功能
- 完全兼容标准net/http
- 简化API开发流程
- 提供丰富的OpenAPI定制选项
Fuego特别适合需要快速开发API并自动生成文档的项目,它减少了开发者的重复工作,同时保持了Go标准库的兼容性。
更多关于golang高效生成OpenAPI 3规范的Web框架插件Fuego的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang高效生成OpenAPI 3规范的Web框架插件Fuego的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用Fuego高效生成OpenAPI 3规范的Golang Web框架插件
Fuego是一个专为Golang Web框架设计的插件,能够高效生成OpenAPI 3.0规范文档。它支持多种流行框架如Gin、Echo等,通过代码注释自动生成API文档,大幅提升开发效率。
Fuego核心特性
- 自动生成OpenAPI 3.0规范
- 支持多种Web框架
- 基于代码注释的文档生成
- 内置Swagger UI集成
- 类型安全的参数定义
安装Fuego
go get github.com/swaggest/fuego
基本使用示例
1. Gin框架集成
package main
import (
"github.com/gin-gonic/gin"
"github.com/swaggest/fuego"
"github.com/swaggest/openapi-go/openapi3"
)
// @title 用户API
// @version 1.0
// @description 用户管理接口
func main() {
r := gin.Default()
// 初始化Fuego
reflector := &openapi3.Reflector{}
fuegoServer := fuego.NewServer(reflector)
// 添加路由
r.GET("/users", GetUsers)
// 注册OpenAPI路由
fuego.RegisterOpenAPI3Route(r, "/openapi.json", fuegoServer)
fuego.RegisterSwaggerUIRoute(r, "/docs", "/openapi.json")
r.Run(":8080")
}
// GetUsers 获取用户列表
// @summary 获取用户列表
// @description 返回所有用户数据
// @tags 用户
// @produce json
// @success 200 {array} User
// @router /users [get]
func GetUsers(c *gin.Context) {
users := []User{
{ID: 1, Name: "张三"},
{ID: 2, Name: "李四"},
}
c.JSON(200, users)
}
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
2. Echo框架集成
package main
import (
"github.com/labstack/echo/v4"
"github.com/swaggest/fuego"
"github.com/swaggest/openapi-go/openapi3"
)
func main() {
e := echo.New()
reflector := &openapi3.Reflector{}
fuegoServer := fuego.NewServer(reflector)
e.GET("/products", GetProducts)
fuego.RegisterOpenAPI3RouteEcho(e, "/openapi.json", fuegoServer)
fuego.RegisterSwaggerUIRouteEcho(e, "/docs", "/openapi.json")
e.Start(":8080")
}
// GetProducts 获取产品列表
// @summary 获取产品
// @description 返回所有产品数据
// @tags 产品
// @param category query string false "产品分类"
// @produce json
// @success 200 {array} Product
// @router /products [get]
func GetProducts(c echo.Context) error {
category := c.QueryParam("category")
products := []Product{
{ID: 1, Name: "产品A", Category: "电子"},
{ID: 2, Name: "产品B", Category: "家居"},
}
if category != "" {
var filtered []Product
for _, p := range products {
if p.Category == category {
filtered = append(filtered, p)
}
}
return c.JSON(200, filtered)
}
return c.JSON(200, products)
}
type Product struct {
ID int `json:"id"`
Name string `json:"name"`
Category string `json:"category"`
}
高级功能
1. 请求体和响应体定义
// CreateUser 创建用户
// @summary 创建新用户
// @tags 用户
// @accept json
// @param request body CreateUserRequest true "用户信息"
// @produce json
// @success 201 {object} User
// @router /users [post]
func CreateUser(c *gin.Context) {
var req CreateUserRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
// 处理创建逻辑
user := User{
ID: 3,
Name: req.Name,
}
c.JSON(201, user)
}
type CreateUserRequest struct {
Name string `json:"name" required:"true" minLength:"2" maxLength:"50"`
Email string `json:"email" format:"email"`
}
2. 认证配置
// 在main函数中配置认证
reflector.SpecEns().SecuritySchemes = map[string]openapi3.SecuritySchemeOrRef{
"BearerAuth": {
SecurityScheme: &openapi3.SecurityScheme{
Type: "http",
Scheme: "bearer",
BearerFormat: "JWT",
},
},
}
// 在路由注释中使用
// GetProfile 获取用户资料
// @summary 获取当前用户资料
// @tags 用户
// @security BearerAuth
// @produce json
// @success 200 {object} User
// @router /profile [get]
func GetProfile(c *gin.Context) {
// 实现代码
}
最佳实践
- 保持注释完整:为每个路由添加完整的注释信息
- 使用结构体验证:利用结构体标签定义参数验证规则
- 分模块组织:为大型项目创建多个OpenAPI文档
- 版本控制:在API路径中包含版本号
- 定期审查:定期检查生成的文档与实际API的一致性
Fuego通过简洁的注释语法和强大的自动生成能力,显著减少了维护API文档的工作量,是Golang Web开发中提升效率的利器。