forked from goadesign/goa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
openapi_v2.go
411 lines (378 loc) · 21 KB
/
openapi_v2.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
// Package openapi produces OpenAPI Specification 2.0 (https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md)
// for the HTTP endpoints.
package openapi
import (
"encoding/json"
"goa.design/goa/expr"
yaml "gopkg.in/yaml.v2"
)
type (
// V2 represents an instance of a Swagger object.
// See https://github.com/OAI/OpenAPI-Specification
V2 struct {
Swagger string `json:"swagger,omitempty" yaml:"swagger,omitempty"`
Info *Info `json:"info,omitempty" yaml:"info,omitempty"`
Host string `json:"host,omitempty" yaml:"host,omitempty"`
BasePath string `json:"basePath,omitempty" yaml:"basePath,omitempty"`
Schemes []string `json:"schemes,omitempty" yaml:"schemes,omitempty"`
Consumes []string `json:"consumes,omitempty" yaml:"consumes,omitempty"`
Produces []string `json:"produces,omitempty" yaml:"produces,omitempty"`
Paths map[string]interface{} `json:"paths" yaml:"paths"`
Definitions map[string]*Schema `json:"definitions,omitempty" yaml:"definitions,omitempty"`
Parameters map[string]*Parameter `json:"parameters,omitempty" yaml:"parameters,omitempty"`
Responses map[string]*Response `json:"responses,omitempty" yaml:"responses,omitempty"`
SecurityDefinitions map[string]*SecurityDefinition `json:"securityDefinitions,omitempty" yaml:"securityDefinitions,omitempty"`
Tags []*Tag `json:"tags,omitempty" yaml:"tags,omitempty"`
ExternalDocs *ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
}
// Info provides metadata about the API. The metadata can be used by the clients if needed,
// and can be presented in the OpenAPI UI for convenience.
Info struct {
Title string `json:"title" yaml:"title"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
TermsOfService string `json:"termsOfService,omitempty" yaml:"termsOfService,omitempty"`
Contact *expr.ContactExpr `json:"contact,omitempty" yaml:"contact,omitempty"`
License *expr.LicenseExpr `json:"license,omitempty" yaml:"license,omitempty"`
Version string `json:"version" yaml:"version"`
Extensions map[string]interface{} `json:"-" yaml:"-"`
}
// Path holds the relative paths to the individual endpoints.
Path struct {
// Ref allows for an external definition of this path item.
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
// Get defines a GET operation on this path.
Get *Operation `json:"get,omitempty" yaml:"get,omitempty"`
// Put defines a PUT operation on this path.
Put *Operation `json:"put,omitempty" yaml:"put,omitempty"`
// Post defines a POST operation on this path.
Post *Operation `json:"post,omitempty" yaml:"post,omitempty"`
// Delete defines a DELETE operation on this path.
Delete *Operation `json:"delete,omitempty" yaml:"delete,omitempty"`
// Options defines a OPTIONS operation on this path.
Options *Operation `json:"options,omitempty" yaml:"options,omitempty"`
// Head defines a HEAD operation on this path.
Head *Operation `json:"head,omitempty" yaml:"head,omitempty"`
// Patch defines a PATCH operation on this path.
Patch *Operation `json:"patch,omitempty" yaml:"patch,omitempty"`
// Parameters is the list of parameters that are applicable for all the operations
// described under this path.
Parameters []*Parameter `json:"parameters,omitempty" yaml:"parameters,omitempty"`
// Extensions defines the swagger extensions.
Extensions map[string]interface{} `json:"-" yaml:"-"`
}
// Operation describes a single API operation on a path.
Operation struct {
// Tags is a list of tags for API documentation control. Tags
// can be used for logical grouping of operations by services or
// any other qualifier.
Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"`
// Summary is a short summary of what the operation does. For maximum readability
// in the swagger-ui, this field should be less than 120 characters.
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
// Description is a verbose explanation of the operation behavior.
// GFM syntax can be used for rich text representation.
Description string `json:"description,omitempty" yaml:"description,omitempty"`
// ExternalDocs points to additional external documentation for this operation.
ExternalDocs *ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
// OperationID is a unique string used to identify the operation.
OperationID string `json:"operationId,omitempty" yaml:"operationId,omitempty"`
// Consumes is a list of MIME types the operation can consume.
Consumes []string `json:"consumes,omitempty" yaml:"consumes,omitempty"`
// Produces is a list of MIME types the operation can produce.
Produces []string `json:"produces,omitempty" yaml:"produces,omitempty"`
// Parameters is a list of parameters that are applicable for this operation.
Parameters []*Parameter `json:"parameters,omitempty" yaml:"parameters,omitempty"`
// Responses is the list of possible responses as they are returned from executing
// this operation.
Responses map[string]*Response `json:"responses,omitempty" yaml:"responses,omitempty"`
// Schemes is the transfer protocol for the operation.
Schemes []string `json:"schemes,omitempty" yaml:"schemes,omitempty"`
// Deprecated declares this operation to be deprecated.
Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`
// Security is a declaration of which security schemes are applied for this operation.
Security []map[string][]string `json:"security,omitempty" yaml:"security,omitempty"`
// Extensions defines the swagger extensions.
Extensions map[string]interface{} `json:"-" yaml:"-"`
}
// Parameter describes a single operation parameter.
Parameter struct {
// Name of the parameter. Parameter names are case sensitive.
Name string `json:"name" yaml:"name"`
// In is the location of the parameter.
// Possible values are "query", "header", "path", "formData" or "body".
In string `json:"in" yaml:"in"`
// Description is a brief description of the parameter.
// GFM syntax can be used for rich text representation.
Description string `json:"description,omitempty" yaml:"description,omitempty"`
// Required determines whether this parameter is mandatory.
Required bool `json:"required" yaml:"required"`
// Schema defining the type used for the body parameter, only if "in" is body
Schema *Schema `json:"schema,omitempty" yaml:"schema,omitempty"`
// properties below only apply if "in" is not body
// Type of the parameter. Since the parameter is not located at the request body,
// it is limited to simple types (that is, not an object).
Type string `json:"type,omitempty" yaml:"type,omitempty"`
// Format is the extending format for the previously mentioned type.
Format string `json:"format,omitempty" yaml:"format,omitempty"`
// AllowEmptyValue sets the ability to pass empty-valued parameters.
// This is valid only for either query or formData parameters and allows you to
// send a parameter with a name only or an empty value. Default value is false.
AllowEmptyValue bool `json:"allowEmptyValue,omitempty" yaml:"allowEmptyValue,omitempty"`
// Items describes the type of items in the array if type is "array".
Items *Items `json:"items,omitempty" yaml:"items,omitempty"`
// CollectionFormat determines the format of the array if type array is used.
// Possible values are csv, ssv, tsv, pipes and multi.
CollectionFormat string `json:"collectionFormat,omitempty" yaml:"collectionFormat,omitempty"`
// Default declares the value of the parameter that the server will use if none is
// provided, for example a "count" to control the number of results per page might
// default to 100 if not supplied by the client in the request.
Default interface{} `json:"default,omitempty" yaml:"default,omitempty"`
Maximum *float64 `json:"maximum,omitempty" yaml:"maximum,omitempty"`
ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty" yaml:"exclusiveMaximum,omitempty"`
Minimum *float64 `json:"minimum,omitempty" yaml:"minimum,omitempty"`
ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty" yaml:"exclusiveMinimum,omitempty"`
MaxLength *int `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`
MinLength *int `json:"minLength,omitempty" yaml:"minLength,omitempty"`
Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
MaxItems *int `json:"maxItems,omitempty" yaml:"maxItems,omitempty"`
MinItems *int `json:"minItems,omitempty" yaml:"minItems,omitempty"`
UniqueItems bool `json:"uniqueItems,omitempty" yaml:"uniqueItems,omitempty"`
Enum []interface{} `json:"enum,omitempty" yaml:"enum,omitempty"`
MultipleOf float64 `json:"multipleOf,omitempty" yaml:"multipleOf,omitempty"`
// Extensions defines the swagger extensions.
Extensions map[string]interface{} `json:"-" yaml:"-"`
}
// Response describes an operation response.
Response struct {
// Description of the response. GFM syntax can be used for rich text representation.
Description string `json:"description,omitempty" yaml:"description,omitempty"`
// Schema is a definition of the response structure. It can be a primitive,
// an array or an object. If this field does not exist, it means no content is
// returned as part of the response. As an extension to the Schema Object, its root
// type value may also be "file".
Schema *Schema `json:"schema,omitempty" yaml:"schema,omitempty"`
// Headers is a list of headers that are sent with the response.
Headers map[string]*Header `json:"headers,omitempty" yaml:"headers,omitempty"`
// Ref references a global API response.
// This field is exclusive with the other fields of Response.
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
// Extensions defines the swagger extensions.
Extensions map[string]interface{} `json:"-" yaml:"-"`
}
// Header represents a header parameter.
Header struct {
// Description is a brief description of the parameter.
// GFM syntax can be used for rich text representation.
Description string `json:"description,omitempty" yaml:"description,omitempty"`
// Type of the header. it is limited to simple types (that is, not an object).
Type string `json:"type,omitempty" yaml:"type,omitempty"`
// Format is the extending format for the previously mentioned type.
Format string `json:"format,omitempty" yaml:"format,omitempty"`
// Items describes the type of items in the array if type is "array".
Items *Items `json:"items,omitempty" yaml:"items,omitempty"`
// CollectionFormat determines the format of the array if type array is used.
// Possible values are csv, ssv, tsv, pipes and multi.
CollectionFormat string `json:"collectionFormat,omitempty" yaml:"collectionFormat,omitempty"`
// Default declares the value of the parameter that the server will use if none is
// provided, for example a "count" to control the number of results per page might
// default to 100 if not supplied by the client in the request.
Default interface{} `json:"default,omitempty" yaml:"default,omitempty"`
Maximum *float64 `json:"maximum,omitempty" yaml:"maximum,omitempty"`
ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty" yaml:"exclusiveMaximum,omitempty"`
Minimum *float64 `json:"minimum,omitempty" yaml:"minimum,omitempty"`
ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty" yaml:"exclusiveMinimum,omitempty"`
MaxLength *int `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`
MinLength *int `json:"minLength,omitempty" yaml:"minLength,omitempty"`
Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
MaxItems *int `json:"maxItems,omitempty" yaml:"maxItems,omitempty"`
MinItems *int `json:"minItems,omitempty" yaml:"minItems,omitempty"`
UniqueItems bool `json:"uniqueItems,omitempty" yaml:"uniqueItems,omitempty"`
Enum []interface{} `json:"enum,omitempty" yaml:"enum,omitempty"`
MultipleOf float64 `json:"multipleOf,omitempty" yaml:"multipleOf,omitempty"`
}
// SecurityDefinition allows the definition of a security scheme that can be used by the
// operations. Supported schemes are basic authentication, an API key (either as a header or
// as a query parameter) and OAuth2's common flows (implicit, password, application and
// access code).
SecurityDefinition struct {
// Type of the security scheme. Valid values are "basic", "apiKey" or "oauth2".
Type string `json:"type" yaml:"type"`
// Description for security scheme
Description string `json:"description,omitempty" yaml:"description,omitempty"`
// Name of the header or query parameter to be used when type is "apiKey".
Name string `json:"name,omitempty" yaml:"name,omitempty"`
// In is the location of the API key when type is "apiKey".
// Valid values are "query" or "header".
In string `json:"in,omitempty" yaml:"in,omitempty"`
// Flow is the flow used by the OAuth2 security scheme when type is "oauth2"
// Valid values are "implicit", "password", "application" or "accessCode".
Flow string `json:"flow,omitempty" yaml:"flow,omitempty"`
// The oauth2 authorization URL to be used for this flow.
AuthorizationURL string `json:"authorizationUrl,omitempty" yaml:"authorizationUrl,omitempty"`
// TokenURL is the token URL to be used for this flow.
TokenURL string `json:"tokenUrl,omitempty" yaml:"tokenUrl,omitempty"`
// Scopes list the available scopes for the OAuth2 security scheme.
Scopes map[string]string `json:"scopes,omitempty" yaml:"scopes,omitempty"`
// Extensions defines the swagger extensions.
Extensions map[string]interface{} `json:"-" yaml:"-"`
}
// Scope corresponds to an available scope for an OAuth2 security scheme.
Scope struct {
// Description for scope
Description string `json:"description,omitempty" yaml:"description,omitempty"`
}
// ExternalDocs allows referencing an external document for extended
// documentation.
ExternalDocs struct {
// Description is a short description of the target documentation.
// GFM syntax can be used for rich text representation.
Description string `json:"description,omitempty" yaml:"description,omitempty"`
// URL for the target documentation.
URL string `json:"url" yaml:"url"`
}
// Items is a limited subset of JSON-Schema's items object. It is used by parameter
// definitions that are not located in "body".
Items struct {
// Type of the items. it is limited to simple types (that is, not an object).
Type string `json:"type,omitempty" yaml:"type,omitempty"`
// Format is the extending format for the previously mentioned type.
Format string `json:"format,omitempty" yaml:"format,omitempty"`
// Items describes the type of items in the array if type is "array".
Items *Items `json:"items,omitempty" yaml:"items,omitempty"`
// CollectionFormat determines the format of the array if type array is used.
// Possible values are csv, ssv, tsv, pipes and multi.
CollectionFormat string `json:"collectionFormat,omitempty" yaml:"collectionFormat,omitempty"`
// Default declares the value of the parameter that the server will use if none is
// provided, for example a "count" to control the number of results per page might
// default to 100 if not supplied by the client in the request.
Default interface{} `json:"default,omitempty" yaml:"default,omitempty"`
Maximum *float64 `json:"maximum,omitempty" yaml:"maximum,omitempty"`
ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty" yaml:"exclusiveMaximum,omitempty"`
Minimum *float64 `json:"minimum,omitempty" yaml:"minimum,omitempty"`
ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty" yaml:"exclusiveMinimum,omitempty"`
MaxLength *int `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`
MinLength *int `json:"minLength,omitempty" yaml:"minLength,omitempty"`
Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
MaxItems *int `json:"maxItems,omitempty" yaml:"maxItems,omitempty"`
MinItems *int `json:"minItems,omitempty" yaml:"minItems,omitempty"`
UniqueItems bool `json:"uniqueItems,omitempty" yaml:"uniqueItems,omitempty"`
Enum []interface{} `json:"enum,omitempty" yaml:"enum,omitempty"`
MultipleOf float64 `json:"multipleOf,omitempty" yaml:"multipleOf,omitempty"`
}
// Tag allows adding meta data to a single tag that is used by the Operation Object. It is
// not mandatory to have a Tag Object per tag used there.
Tag struct {
// Name of the tag.
Name string `json:"name,omitempty" yaml:"name,omitempty"`
// Description is a short description of the tag.
// GFM syntax can be used for rich text representation.
Description string `json:"description,omitempty" yaml:"description,omitempty"`
// ExternalDocs is additional external documentation for this tag.
ExternalDocs *ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
// Extensions defines the swagger extensions.
Extensions map[string]interface{} `json:"-" yaml:"-"`
}
// These types are used in marshalJSON() to avoid recursive call of json.Marshal().
_Info Info
_Path Path
_Operation Operation
_Parameter Parameter
_Response Response
_SecurityDefinition SecurityDefinition
_Tag Tag
)
func marshalJSON(v interface{}, extensions map[string]interface{}) ([]byte, error) {
marshaled, err := json.Marshal(v)
if err != nil {
return nil, err
}
if len(extensions) == 0 {
return marshaled, nil
}
var unmarshaled interface{}
if err := json.Unmarshal(marshaled, &unmarshaled); err != nil {
return nil, err
}
asserted := unmarshaled.(map[string]interface{})
for k, v := range extensions {
asserted[k] = v
}
merged, err := json.Marshal(asserted)
if err != nil {
return nil, err
}
return merged, nil
}
// MarshalJSON returns the JSON encoding of i.
func (i Info) MarshalJSON() ([]byte, error) {
return marshalJSON(_Info(i), i.Extensions)
}
// MarshalJSON returns the JSON encoding of p.
func (p Path) MarshalJSON() ([]byte, error) {
return marshalJSON(_Path(p), p.Extensions)
}
// MarshalJSON returns the JSON encoding of o.
func (o Operation) MarshalJSON() ([]byte, error) {
return marshalJSON(_Operation(o), o.Extensions)
}
// MarshalJSON returns the JSON encoding of p.
func (p Parameter) MarshalJSON() ([]byte, error) {
return marshalJSON(_Parameter(p), p.Extensions)
}
// MarshalJSON returns the JSON encoding of r.
func (r Response) MarshalJSON() ([]byte, error) {
return marshalJSON(_Response(r), r.Extensions)
}
// MarshalJSON returns the JSON encoding of s.
func (s SecurityDefinition) MarshalJSON() ([]byte, error) {
return marshalJSON(_SecurityDefinition(s), s.Extensions)
}
// MarshalJSON returns the JSON encoding of t.
func (t Tag) MarshalJSON() ([]byte, error) {
return marshalJSON(_Tag(t), t.Extensions)
}
func marshalYAML(v interface{}, extensions map[string]interface{}) (interface{}, error) {
if len(extensions) == 0 {
return v, nil
}
marshaled, err := yaml.Marshal(v)
if err != nil {
return nil, err
}
var unmarshaled map[string]interface{}
if err := yaml.Unmarshal(marshaled, &unmarshaled); err != nil {
return nil, err
}
for k, v := range extensions {
unmarshaled[k] = v
}
return unmarshaled, nil
}
// MarshalYAML returns value which marshaled in place of the original value
func (i Info) MarshalYAML() (interface{}, error) {
return marshalYAML(_Info(i), i.Extensions)
}
// MarshalYAML returns value which marshaled in place of the original value
func (p Path) MarshalYAML() (interface{}, error) {
return marshalYAML(_Path(p), p.Extensions)
}
// MarshalYAML returns value which marshaled in place of the original value
func (o Operation) MarshalYAML() (interface{}, error) {
return marshalYAML(_Operation(o), o.Extensions)
}
// MarshalYAML returns value which marshaled in place of the original value
func (p Parameter) MarshalYAML() (interface{}, error) {
return marshalYAML(_Parameter(p), p.Extensions)
}
// MarshalYAML returns value which marshaled in place of the original value
func (r Response) MarshalYAML() (interface{}, error) {
return marshalYAML(_Response(r), r.Extensions)
}
// MarshalYAML returns value which marshaled in place of the original value
func (s SecurityDefinition) MarshalYAML() (interface{}, error) {
return marshalYAML(_SecurityDefinition(s), s.Extensions)
}
// MarshalYAML returns value which marshaled in place of the original value
func (t Tag) MarshalYAML() (interface{}, error) {
return marshalYAML(_Tag(t), t.Extensions)
}