Skip to content

Commit

Permalink
Merge pull request #587 from danielgtaylor/request-description
Browse files Browse the repository at this point in the history
fix: allow setting request description and still gen schema
  • Loading branch information
danielgtaylor authored Sep 23, 2024
2 parents ff80e71 + 1954c15 commit 8313d66
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 22 deletions.
47 changes: 25 additions & 22 deletions huma.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,30 +572,30 @@ func Register[I, O any](api API, op Operation, handler func(context.Context, *I)
hasInputBody = true
inputBodyIndex = f.Index
if op.RequestBody == nil {
required := f.Type.Kind() != reflect.Ptr && f.Type.Kind() != reflect.Interface
if f.Tag.Get("required") == "true" {
required = true
}
op.RequestBody = &RequestBody{}
}

contentType := "application/json"
if c := f.Tag.Get("contentType"); c != "" {
contentType = c
}
hint := getHint(inputType, f.Name, op.OperationID+"Request")
if nameHint := f.Tag.Get("nameHint"); nameHint != "" {
hint = nameHint
}
s := SchemaFromField(registry, f, hint)
required := f.Type.Kind() != reflect.Ptr && f.Type.Kind() != reflect.Interface
if f.Tag.Get("required") == "true" {
required = true
}

op.RequestBody = &RequestBody{
Required: required,
Content: map[string]*MediaType{
contentType: {
Schema: s,
},
},
}
contentType := "application/json"
if c := f.Tag.Get("contentType"); c != "" {
contentType = c
}
hint := getHint(inputType, f.Name, op.OperationID+"Request")
if nameHint := f.Tag.Get("nameHint"); nameHint != "" {
hint = nameHint
}
s := SchemaFromField(registry, f, hint)

op.RequestBody.Required = required

if op.RequestBody.Content == nil {
op.RequestBody.Content = map[string]*MediaType{}
}
op.RequestBody.Content[contentType] = &MediaType{Schema: s}

if op.BodyReadTimeout == 0 {
// 5 second default
Expand All @@ -615,10 +615,13 @@ func Register[I, O any](api API, op Operation, handler func(context.Context, *I)
if op.RequestBody == nil {
op.RequestBody = &RequestBody{
Required: true,
Content: map[string]*MediaType{},
}
}

if op.RequestBody.Content == nil {
op.RequestBody.Content = map[string]*MediaType{}
}

contentType := "application/octet-stream"

if f.Type.String() == "multipart.Form" {
Expand Down
36 changes: 36 additions & 0 deletions huma_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,42 @@ func TestFeatures(t *testing.T) {
// Headers: map[string]string{"Content-Type": "application/json"},
Body: `{"name":"foo"}`,
},
{
Name: "request-body-description",
Register: func(t *testing.T, api huma.API) {
huma.Register(api, huma.Operation{
Method: http.MethodPut,
Path: "/body",
RequestBody: &huma.RequestBody{
Description: "A description",
},
}, func(ctx context.Context, input *struct {
Body struct {
Name string `json:"name"`
}
}) (*struct{}, error) {
assert.Equal(t, "foo", input.Body.Name)
return nil, nil
})
// Note: the description should be set, but *also* the generated
// schema should be present since we didn't set it up ourselves.
b, _ := api.OpenAPI().Paths["/body"].Put.RequestBody.MarshalJSON()
assert.JSONEq(t, `{
"description": "A description",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Request"
}
}
}
}`, string(b))
},
Method: http.MethodPut,
URL: "/body",
Body: `{"name":"foo"}`,
},
{
Name: "request-body-nested-struct-readOnly",
Register: func(t *testing.T, api huma.API) {
Expand Down

0 comments on commit 8313d66

Please sign in to comment.