Skip to content

Commit 535dc17

Browse files
committed
feat: add a way to set a description to the schema request body
1 parent fe54d35 commit 535dc17

File tree

3 files changed

+60
-28
lines changed

3 files changed

+60
-28
lines changed

openapi/generator.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,14 @@ func (g *Generator) setOperationParams(op *Operation, t, parent reflect.Type, al
458458
}
459459
sch := op.RequestBody.Content[mt].Schema
460460
if sch != nil {
461+
// Get description
462+
if t.Implements(tofDescriptor) {
463+
i, ok := reflect.New(t).Interface().(Descriptor)
464+
if ok {
465+
sch.Schema.Description = i.Description()
466+
}
467+
}
468+
461469
name := strings.Title(op.ID) + "Input"
462470
g.api.Components.Schemas[name] = sch
463471
op.RequestBody.Content[mt].Schema = &SchemaOrRef{Reference: &Reference{

openapi/generator_test.go

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -452,35 +452,41 @@ func diffJSON(a, b []byte) (bool, error) {
452452
return reflect.DeepEqual(j2, j), nil
453453
}
454454

455+
type InEmbed struct {
456+
D int `query:"xd" enum:"1,2,3" default:"1"`
457+
E bool `query:"e"`
458+
F *string `json:"f" description:"This is F"`
459+
G []byte `validate:"required"`
460+
H uint16 `binding:"-"`
461+
K []string `query:"k" enum:"aaa,bbb,ccc"`
462+
}
463+
type inEmbedPrivate struct {
464+
I string `query:"i"`
465+
}
466+
type h string
467+
type In struct {
468+
*In // ignored, recusrive embedding
469+
*InEmbed
470+
*inEmbedPrivate
471+
472+
A int `path:"a" description:"This is A" deprecated:"oui"`
473+
B time.Time `query:"b" validate:"required" description:"This is B"`
474+
C string `header:"X-Test-C" description:"This is C" default:"test"`
475+
d int // ignored, unexported field
476+
E int `path:"a"` // ignored, duplicate of A
477+
F *string `json:"f"` // ignored, duplicate of F in InEmbed
478+
G *inEmbedPrivate
479+
h // ignored, embedded field of non-struct type
480+
481+
}
482+
483+
func (i In) Description() string {
484+
return "Test input schema description"
485+
}
486+
455487
// TestAddOperation tests that an operation can be added
456488
// and generates the according specification.
457489
func TestAddOperation(t *testing.T) {
458-
type InEmbed struct {
459-
D int `query:"xd" enum:"1,2,3" default:"1"`
460-
E bool `query:"e"`
461-
F *string `json:"f" description:"This is F"`
462-
G []byte `validate:"required"`
463-
H uint16 `binding:"-"`
464-
K []string `query:"k" enum:"aaa,bbb,ccc"`
465-
}
466-
type inEmbedPrivate struct {
467-
I string `query:"i"`
468-
}
469-
type h string
470-
type In struct {
471-
*In // ignored, recusrive embedding
472-
*InEmbed
473-
*inEmbedPrivate
474-
475-
A int `path:"a" description:"This is A" deprecated:"oui"`
476-
B time.Time `query:"b" validate:"required" description:"This is B"`
477-
C string `header:"X-Test-C" description:"This is C" default:"test"`
478-
d int // ignored, unexported field
479-
E int `path:"a"` // ignored, duplicate of A
480-
F *string `json:"f"` // ignored, duplicate of F in InEmbed
481-
G *inEmbedPrivate
482-
h // ignored, embedded field of non-struct type
483-
}
484490
type CustomError struct{}
485491

486492
var Header string
@@ -524,6 +530,17 @@ func TestAddOperation(t *testing.T) {
524530
if err != nil {
525531
t.Error(err)
526532
}
533+
534+
requestBodyName := infos.ID + "Input"
535+
requestBody, ok := g.API().Components.Schemas[requestBodyName]
536+
if !ok {
537+
t.Errorf("expected to found item for schema %s", requestBodyName)
538+
}
539+
540+
if requestBody.Schema.Description == "" {
541+
t.Errorf("expected to found description for schema %s", requestBodyName)
542+
}
543+
527544
// Add another operation with no input/output type.
528545
// No parameters should be present, and a response
529546
// matching the default status code used by tonic

openapi/types.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ import (
1212
)
1313

1414
var (
15-
tofDataType = reflect.TypeOf((*DataType)(nil)).Elem()
16-
tofNullable = reflect.TypeOf((*Nullable)(nil)).Elem()
15+
tofDataType = reflect.TypeOf((*DataType)(nil)).Elem()
16+
tofNullable = reflect.TypeOf((*Nullable)(nil)).Elem()
17+
tofDescriptor = reflect.TypeOf((*Descriptor)(nil)).Elem()
1718

1819
// Native.
1920
tofTime = reflect.TypeOf(time.Time{})
@@ -49,6 +50,12 @@ type Exampler interface {
4950
ParseExample(v string) (interface{}, error)
5051
}
5152

53+
// Descriptor is the interface implemented by the RequestBody input schema
54+
// that provides a description for this schema kind
55+
type Descriptor interface {
56+
Description() string
57+
}
58+
5259
// Nullable is the interface implemented by the types
5360
// that can be nullable.
5461
type Nullable interface {

0 commit comments

Comments
 (0)