Skip to content

响应输出#

响应可以具有可选的状态码、标头和/或主体。像输入一样,它们使用标准的 Go 结构体来描述响应的 entirety(全部)。

状态码#

Huma 使用以下默认响应状态码:

  • 200 用于具有主体的响应
  • 204 用于不具有主体的响应

您可以通过两种方式覆盖此行为。第一种是在操作注册时设置 huma.Operation DefaultStatus 字段。

code.go
// 注册一个操作,默认状态码为 201。
huma.Register(api, huma.Operation{
	OperationID:  "create-thing",
	Method:       http.MethodPost,
	Path:         "/things",
	Summary:      "Create a thing",
	DefaultStatus: 201,
}, func(ctx context.Context, input ThingRequest) (*struct{}, error) {
	// Do nothing...
	return nil, nil
}

如果响应码需要是 动态 的,您可以在响应结构体中使用特殊的 Status 字段。这不是推荐的做法,但如果需要的话是可用的。

code.go
type ThingResponse struct {
	Status int
}

huma.Register(api, huma.Operation{
	OperationID:  "get-thing",
	Method:       http.MethodGet,
	Path:         "/things/{thing-id}",
	Summary:      "Get a thing by ID",
}, func(ctx context.Context, input ThingRequest) (*struct{}, error) {
	// Create a response and set the dynamic status
	resp := &ThingResponse{}
	if input.ID < 500 {
		resp.Status = 200
	} else {
		// This is a made-up status code used for newer things.
		resp.Status = 250
	}
	return resp, nil
}

动态状态

设置默认状态码比在响应结构体中使用 Status 字段更常见得多!

标头#

标头由响应结构体上的字段设置。以下是可用的标签:

标签 描述 示例
header 响应标头的名称 header:"Authorization"
timeFormat time.Time 的格式 timeFormat:"Mon, 02 Jan 2006 15:04:05 GMT"

这是一个具有不同类型多个标头的响应的示例:

code.go
// 示例结构体,具有多个标头
type MyOutput struct {
	ContentType  string    `header:"Content-Type"`
	LastModified time.Time `header:"Last-Modified"`
	MyHeader     int       `header:"My-Header"`
}

如果字段类型实现了 fmt.Stringer 接口,则会使用该接口将值转换为字符串。

设置 vs. 追加#

默认情况下,标头会被设置到响应中,这会覆盖同名的任何现有标头。如果您想向现有标头追加,可以使用值数组而不是单个值。

code.go
type MyOutput struct {
	MyHeader []string `header:"My-Header"`
}

如果您只想追加一个标头,可以使用包含单个值的切片。

您可以通过使用 Set-Cookie 标头在响应中设置 Cookie。可以使用 http.Cookie 类型来表示 Cookie,而无需手动将其转换为字符串。

code.go
type MyOutput struct {
	SetCookie http.Cookie `header:"Set-Cookie"`
}

huma.Register(api, huma.Operation{
	OperationID: "set-cookie",
	Method:      http.MethodGet,
	Path:        "/set-cookie",
	Summary:     "Set a cookie",
}, func(ctx context.Context, *struct{}) (*MyOutput, error) {
	// Create a response and set the cookie
	resp := &MyOutput{
		SetCookie: http.Cookie{
			Name:  "session",
			Value: "123",
		},
	}
	return resp, nil
}

您可以通过使用像 []http.Cookie 这样的切片来设置多个 Cookie。

主体#

特殊的结构体字段 Body 将被视为响应主体,并且可以引用任何其他类型,或者您可以内联嵌入结构体或切片。如果没有存在,则会根据注册的序列化类型,通过客户端驱动的内容协商与服务器一起选择默认的 Content-Type 标头。

示例:

code.go
type MyBody struct {
	Name string `json:"name"`
}

type MyOutput struct {
	Body MyBody
}

使用 []byte 类型来绕过 serialization

code.go
type MyOutput struct {
	Body []byte
}

您也可以流式传输响应主体,请参阅 streaming 以获取更多详细信息。

深入了解#