-
-
Notifications
You must be signed in to change notification settings - Fork 411
/
response.go
152 lines (127 loc) · 4.03 KB
/
response.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package openapi3
import (
"context"
"errors"
"fmt"
"sort"
"strconv"
"github.com/go-openapi/jsonpointer"
"github.com/getkin/kin-openapi/jsoninfo"
)
// Responses is specified by OpenAPI/Swagger 3.0 standard.
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#responsesObject
type Responses map[string]*ResponseRef
var _ jsonpointer.JSONPointable = (*Responses)(nil)
func NewResponses() Responses {
r := make(Responses)
r["default"] = &ResponseRef{Value: NewResponse().WithDescription("")}
return r
}
func (responses Responses) Default() *ResponseRef {
return responses["default"]
}
func (responses Responses) Get(status int) *ResponseRef {
return responses[strconv.FormatInt(int64(status), 10)]
}
// Validate returns an error if Responses does not comply with the OpenAPI spec.
func (responses Responses) Validate(ctx context.Context) error {
if len(responses) == 0 {
return errors.New("the responses object MUST contain at least one response code")
}
keys := make([]string, 0, len(responses))
for key := range responses {
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
v := responses[key]
if err := v.Validate(ctx); err != nil {
return err
}
}
return nil
}
// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable
func (responses Responses) JSONLookup(token string) (interface{}, error) {
ref, ok := responses[token]
if ok == false {
return nil, fmt.Errorf("invalid token reference: %q", token)
}
if ref != nil && ref.Ref != "" {
return &Ref{Ref: ref.Ref}, nil
}
return ref.Value, nil
}
// Response is specified by OpenAPI/Swagger 3.0 standard.
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#responseObject
type Response struct {
ExtensionProps `json:"-" yaml:"-"`
Description *string `json:"description,omitempty" yaml:"description,omitempty"`
Headers Headers `json:"headers,omitempty" yaml:"headers,omitempty"`
Content Content `json:"content,omitempty" yaml:"content,omitempty"`
Links Links `json:"links,omitempty" yaml:"links,omitempty"`
}
func NewResponse() *Response {
return &Response{}
}
func (response *Response) WithDescription(value string) *Response {
response.Description = &value
return response
}
func (response *Response) WithContent(content Content) *Response {
response.Content = content
return response
}
func (response *Response) WithJSONSchema(schema *Schema) *Response {
response.Content = NewContentWithJSONSchema(schema)
return response
}
func (response *Response) WithJSONSchemaRef(schema *SchemaRef) *Response {
response.Content = NewContentWithJSONSchemaRef(schema)
return response
}
// MarshalJSON returns the JSON encoding of Response.
func (response *Response) MarshalJSON() ([]byte, error) {
return jsoninfo.MarshalStrictStruct(response)
}
// UnmarshalJSON sets Response to a copy of data.
func (response *Response) UnmarshalJSON(data []byte) error {
return jsoninfo.UnmarshalStrictStruct(data, response)
}
// Validate returns an error if Response does not comply with the OpenAPI spec.
func (response *Response) Validate(ctx context.Context) error {
if response.Description == nil {
return errors.New("a short description of the response is required")
}
if vo := getValidationOptions(ctx); !vo.ExamplesValidationDisabled {
vo.examplesValidationAsReq, vo.examplesValidationAsRes = false, true
}
if content := response.Content; content != nil {
if err := content.Validate(ctx); err != nil {
return err
}
}
headers := make([]string, 0, len(response.Headers))
for name := range response.Headers {
headers = append(headers, name)
}
sort.Strings(headers)
for _, name := range headers {
header := response.Headers[name]
if err := header.Validate(ctx); err != nil {
return err
}
}
links := make([]string, 0, len(response.Links))
for name := range response.Links {
links = append(links, name)
}
sort.Strings(links)
for _, name := range links {
link := response.Links[name]
if err := link.Validate(ctx); err != nil {
return err
}
}
return nil
}