Skip to content

BYOR (自带路由器)#

Huma 被设计为路由器无关的,从而实现在大量组织中的现有和新服务中的渐进式采用。这意味着您可以使用任何您想要的路由器,甚至编写自己的。唯一的要求是实现一个小的 huma.Adapter 接口。这就是 Huma 与您的路由器集成的途径。

适配器位于 adapters 目录中,并以它们支持的路由器命名。许多常见的路由器开箱即用支持(按字母顺序):

新适配器

编写您自己的适配器快速且简单,并接受为内置添加额外适配器的 PR。

Chi 示例#

适配器通过包装您的路由器并提供描述 API 的 Huma 配置对象来实例化。这里是一个使用 Chi 的简单示例:

main.go
import (
	"github.com/danielgtaylor/huma/v2"
	"github.com/danielgtaylor/huma/v2/adapters/humachi"
	"github.com/go-chi/chi/v5"
)

// Create your router.
router := chi.NewMux()

// Wrap the router with Huma to create an API instance.
api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0"))

// Register your operations with the API.
// ...

// Start the server!
http.ListenAndServe(":8888", r)

对于使用 Chi v4 的现有服务,您可以使用 humachi.NewV4 代替。

路由组和基础 URL#

许多路由器支持在公共基础 URL 路径下对操作进行分组。这对于 API 版本控制或将相关操作分组在一起非常有用。Huma 的路由器适配器可以使用这些路由组来实例化。您可以设置 OpenAPI().Servers 切片以包含组的基础 URL 路径,从而为文档和模式生成正确的 URL。这里是一个示例:

main.go
mux := chi.NewMux()
mux.Route("/api", func(r chi.Router) {
	config := huma.DefaultConfig("My API", "1.0.0")
	config.Servers = []*huma.Server{
		{URL: "https://example.com/api"},
	}
	api = humachi.New(r, config)

	// Register operations...
	huma.Get(api, "/demo", func(ctx context.Context, input *struct{}) (*struct{}, error) {
		// TODO: Implement me!
		return nil, nil
	})
})
http.ListenAndServe("localhost:8888", mux)

OpenAPI、文档、模式等将全部带有 /api 前缀生成。

Shell
# Call the demo operation
restish :8888/api/demo

# Get the OpenAPI
restish :8888/api/openapi.yaml

支持以下场景:

服务器基础 URL 路由组 注册路径 客户端请求和描述
- - /api/demo GET /api/demo
默认的简单情况。
/api - /demo GET /api/demoGET /demo
例如,一个 API 网关,它在剥离 /api 前缀后将请求转发到服务。
/api /api /demo GET /api/demo
带有路由组的未修改请求。

深入了解#

适配器将特定于路由器的请求上下文(如 http.Requestfiber.Ctx)转换为路由器无关的 huma.Context,然后用于调用您的操作处理函数。

graph LR
	Request([Request])
	OperationHandler[Operation Handler]

	Request --> Router
	Router -->|http.Request<br>fiber.Ctx<br>etc| huma.Adapter
	subgraph huma.API
		huma.Adapter -->|huma.Context| OperationHandler
	end