Skip to content

Commit

Permalink
Allow providing name hints using tags for anonymous body structs
Browse files Browse the repository at this point in the history
  • Loading branch information
lsdch committed Apr 26, 2024
1 parent ed2c3cd commit 7ab1280
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 3 deletions.
13 changes: 10 additions & 3 deletions huma.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,8 +582,11 @@ func Register[I, O any](api API, op Operation, handler func(context.Context, *I)
if c := f.Tag.Get("contentType"); c != "" {
contentType = c
}

s := SchemaFromField(registry, f, getHint(inputType, f.Name, op.OperationID+"Request"))
hint := getHint(inputType, f.Name, op.OperationID+"Request")
if nameHint := f.Tag.Get("name-hint"); nameHint != "" {
hint = nameHint
}
s := SchemaFromField(registry, f, hint)

op.RequestBody = &RequestBody{
Required: required,
Expand Down Expand Up @@ -708,7 +711,11 @@ func Register[I, O any](api API, op Operation, handler func(context.Context, *I)
op.Responses[statusStr].Headers = map[string]*Param{}
}
if !outBodyFunc {
outSchema := SchemaFromField(registry, f, getHint(outputType, f.Name, op.OperationID+"Response"))
hint := getHint(outputType, f.Name, op.OperationID+"Response")
if nameHint := f.Tag.Get("name-hint"); nameHint != "" {
hint = nameHint
}
outSchema := SchemaFromField(registry, f, hint)
if op.Responses[statusStr].Content == nil {
op.Responses[statusStr].Content = map[string]*MediaType{}
}
Expand Down
54 changes: 54 additions & 0 deletions huma_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,32 @@ func TestFeatures(t *testing.T) {
assert.Equal(t, http.StatusBadRequest, resp.Code)
},
},
{
Name: "request-body-name-hint",
Register: func(t *testing.T, api huma.API) {
huma.Register(api, huma.Operation{
Method: http.MethodPut,
Path: "/body",
}, func(ctx context.Context, input *struct {
Body struct {
Name string `json:"name"`
} `name-hint:"ANameHint"`
}) (*struct{}, error) {
return nil, nil
})

registry := api.OpenAPI().Components.Schemas
origType := registry.TypeFromRef(
api.OpenAPI().Paths["/body"].Put.RequestBody.Content["application/json"].Schema.Ref,
)
assert.Equal(t, "ANameHint",
huma.DefaultSchemaNamer(origType, "ANameHint"),
)
},
Method: http.MethodPut,
URL: "/body",
Body: `{"name": "Name"}`,
},
{
Name: "request-ptr-body-required",
Register: func(t *testing.T, api huma.API) {
Expand Down Expand Up @@ -1009,6 +1035,34 @@ Content of example2.txt.
assert.Equal(t, "application/custom-type", resp.Header().Get("Content-Type"))
},
},
{
Name: "response-body-name-hint",
Register: func(t *testing.T, api huma.API) {
type Resp struct {
Body struct {
Greeting string `json:"greeting" `
} `name-hint:"GreetingResp"`
}
huma.Register(api, huma.Operation{
Method: http.MethodGet,
Path: "/response",
}, func(ctx context.Context, input *struct{}) (*Resp, error) {
resp := &Resp{}
resp.Body.Greeting = "Hello, world!"
return resp, nil
})

registry := api.OpenAPI().Components.Schemas
origType := registry.TypeFromRef(
api.OpenAPI().Paths["/response"].Get.Responses["200"].Content["application/json"].Schema.Ref,
)
assert.Equal(t, "GreetingResp",
huma.DefaultSchemaNamer(origType, "GreetingResp"),
)
},
Method: http.MethodGet,
URL: "/response",
},
{
Name: "response",
Register: func(t *testing.T, api huma.API) {
Expand Down

0 comments on commit 7ab1280

Please sign in to comment.