package main
import (
"context"
"fmt"
"net/http"
"github.com/danielgtaylor/huma/v2"
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/go-chi/chi/v5"
_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)
// CLI 的选项。
type Options struct {
Port int `help:"监听端口" short:"p" default:"8888"`
}
// GreetingOutput 表示问候操作响应。
type GreetingOutput struct {
Body struct {
Message string `json:"message" example:"Hello, world!" doc:"问候消息"`
}
}
// ReviewInput 表示评论操作请求。
type ReviewInput struct {
Body struct {
Author string `json:"author" maxLength:"10" doc:"评论作者"`
Rating int `json:"rating" minimum:"1" maximum:"5" doc:"1 到 5 的评分"`
Message string `json:"message,omitempty" maxLength:"100" doc:"评论消息"`
}
}
func main() {
// 创建一个 CLI 应用,它接受端口选项。
cli := humacli.New(func(hooks humacli.Hooks, options *Options) {
// 创建一个新的路由器和 API
router := chi.NewMux()
api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0"))
// 注册 GET /greeting/{name}
huma.Register(api, huma.Operation{
OperationID: "get-greeting",
Method: http.MethodGet,
Path: "/greeting/{name}",
Summary: "获取问候语",
Description: "通过姓名获取一个人的问候语。",
Tags: []string{"Greetings"},
}, func(ctx context.Context, input *struct{
Name string `path:"name" maxLength:"30" example:"world" doc:"要问候的姓名"`
}) (*GreetingOutput, error) {
resp := &GreetingOutput{}
resp.Body.Message = fmt.Sprintf("Hello, %s!", input.Name)
return resp, nil
})
// 注册 POST /reviews
huma.Register(api, huma.Operation{
OperationID: "post-review",
Method: http.MethodPost,
Path: "/reviews",
Summary: "发布评论",
Tags: []string{"Reviews"},
DefaultStatus: http.StatusCreated,
}, func(ctx context.Context, i *ReviewInput) (*struct{}, error) {
// TODO: 在数据存储中保存评论。
return nil, nil
})
// 告诉 CLI 如何启动你的服务器。
hooks.OnStart(func() {
fmt.Printf("Starting server on port %d...\n", options.Port)
http.ListenAndServe(fmt.Sprintf(":%d", options.Port), router)
})
})
// 运行 CLI。当传递无命令时,它启动服务器。
cli.Run()
}