Skip to content

您的第一个 API#

让我们构建一个简单的 API,它会向人们问好。我们将使用 URL 路径参数接收人的姓名,并以包含问候消息的 JSON 正文作为响应。以下是高层 API 设计:

API 设计
Request:
GET /greeting/{name}

Response:
{
	"message": "Hello, {name}!"
}

响应输出#

首先创建一个新文件 main.go,并添加问候操作的响应输出模型,该模型有一个包含 message 字段的正文,用于问候消息:

main.go
1
2
3
4
5
6
7
8
package main

// GreetingOutput represents the greeting operation response.
type GreetingOutput struct {
	Body struct {
		Message string `json:"message" example:"Hello, world!" doc:"Greeting message"`
	}
}

请求和响应可以定义一个名为 Body 的字段,用于序列化或反序列化请求或响应正文。

exampledoc 标签用于通过 OpenAPI 生成友好的 API 文档。

现在您的目录结构应该如下所示:

目录结构
my-api/
  |-- go.mod
  |-- go.sum
	|-- main.go

路由器与 API#

让我们创建一个路由器,它将处理将传入请求路由到正确的操作处理程序,以及一个新的 API 实例,我们可以在其中注册操作。

main.go
package main

import (
	"net/http"

	"github.com/danielgtaylor/huma/v2"
	"github.com/danielgtaylor/huma/v2/adapters/humachi"
	"github.com/go-chi/chi/v5"

	_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// GreetingOutput represents the greeting operation response.
type GreetingOutput struct {
	Body struct {
		Message string `json:"message" example:"Hello, world!" doc:"Greeting message"`
	}
}

func main() {
	// Create a new router & API
	router := chi.NewMux()
	api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0"))

	// TODO: Register operations...

	// Start the server!
	http.ListenAndServe("127.0.0.1:8888", router)
}

路由器

我们在这个示例中使用 Chi,但如果您想使用内置的 Go 1.22+ 路由器,可以这样做:

main.go
router := http.NewServeMux()
api := humago.New(router, huma.DefaultConfig("My API", "1.0.0"))

许多其他路由器也被支持

操作#

使用 Huma API 实例注册操作,包括它如何映射到 URL。处理函数将接收一个定义其输入的结构体(在本例中是一个名为 name 的路径参数),并返回我们上面构建的 GreetingOutput 模型。

main.go
package main

import (
	"context"
	"fmt"
	"net/http"

	"github.com/danielgtaylor/huma/v2"
	"github.com/danielgtaylor/huma/v2/adapters/humachi"
	"github.com/go-chi/chi/v5"

	_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// GreetingOutput represents the greeting operation response.
type GreetingOutput struct {
	Body struct {
		Message string `json:"message" example:"Hello, world!" doc:"Greeting message"`
	}
}

func main() {
	// Create a new router & API.
	router := chi.NewMux()
	api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0"))

	// Register GET /greeting/{name} handler.
	huma.Get(api, "/greeting/{name}", func(ctx context.Context, input *struct{
		Name string `path:"name" maxLength:"30" example:"world" doc:"Name to greet"`
	}) (*GreetingOutput, error) {
		resp := &GreetingOutput{}
		resp.Body.Message = fmt.Sprintf("Hello, %s!", input.Name)
		return resp, nil
	})

	// Start the server!
	http.ListenAndServe("127.0.0.1:8888", router)
}

path 标签告诉 Huma 此字段应从 URL 路径中读取。maxLength 标签告诉 Huma 名称不得超过 30 个字符。

main.go 下载依赖项:

$ go mod tidy

恭喜!这是一个完全功能的 Huma API!

调用 API#

让我们测试一下!启动服务器:

$ go run .

在另一个终端窗口中使用 Restish 或 curl 向 API 发送请求:

终端
# 从 API 获取问候
$ curl http://localhost:8888/greeting/world

模式

现在您可以忽略 Link 标头和 $schema 字段。这些是由 Huma 自动添加的,以帮助客户端发现有关 API 的信息,并提供编辑器中的自动补全和 linting 等功能。

API 文档#

访问 http://localhost:8888/docs 查看 API 的交互式生成文档。它应该看起来像这样:

生成的 API 文档

使用文档页面右上角的面板,您可以向 API 发送请求并查看响应。

这些文档是从 OpenAPI 规范生成的。您可以使用此文件生成文档、客户端库、命令行客户端、模拟服务器等。Huma 提供了两个版本。推荐使用 OpenAPI 3.1,但 OpenAPI 3.0.3 也可用以兼容旧工具:

增强文档#

您可以使用 huma.Register 向 OpenAPI 规范添加更多信息,例如带有 Markdown 的描述、示例、标签等。huma.Operation 结构体提供了对 OpenAPI 的完全访问,包括添加扩展的能力。有关更多详细信息,请参阅 huma.Operation 结构体。

main.go
package main

import (
	"context"
	"fmt"
	"net/http"

	"github.com/danielgtaylor/huma/v2"
	"github.com/danielgtaylor/huma/v2/adapters/humachi"
	"github.com/go-chi/chi/v5"

	_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// GreetingOutput represents the greeting operation response.
type GreetingOutput struct {
	Body struct {
		Message string `json:"message" example:"Hello, world!" doc:"Greeting message"`
	}
}

func main() {
	// Create a new router & API
	router := chi.NewMux()
	api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0"))

	// Register GET /greeting/{name}
	huma.Register(api, huma.Operation{
		OperationID: "get-greeting",
		Method:      http.MethodGet,
		Path:        "/greeting/{name}",
		Summary:     "Get a greeting",
		Description: "Get a greeting for a person by name.",
		Tags:        []string{"Greetings"},
	}, func(ctx context.Context, input *struct{
		Name string `path:"name" maxLength:"30" example:"world" doc:"Name to greet"`
	}) (*GreetingOutput, error) {
		resp := &GreetingOutput{}
		resp.Body.Message = fmt.Sprintf("Hello, %s!", input.Name)
		return resp, nil
	})

	// Start the server!
	http.ListenAndServe("127.0.0.1:8888", router)
}

现在重新启动服务器并查看您的更新的文档!

回顾#

恭喜!您刚刚学习了:

  • 创建 Huma 输入和输出模型
  • 使用 Huma 创建 Golang REST API
  • 如何向 API 发送请求
  • 如何查看生成的文档

继续阅读,学习如何使用更多功能提升您的 API。