-
Notifications
You must be signed in to change notification settings - Fork 0
/
spec.go
445 lines (396 loc) · 20.1 KB
/
spec.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
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
package openapi
import "encoding/json"
// OpenAPI represents the root document object of
// an OpenAPI document.
type OpenAPI struct {
OpenAPI string `json:"openapi" yaml:"openapi"`
Info *Info `json:"info" yaml:"info"`
Servers []*Server `json:"servers,omitempty" yaml:"servers,omitempty"`
Paths Paths `json:"paths" yaml:"paths"`
Components *Components `json:"components,omitempty" yaml:"components,omitempty"`
Tags []*Tag `json:"tags,omitempty" yaml:"tags,omitempty"`
Security []*SecurityRequirement `json:"security,omitempty" yaml:"security,omitempty"`
XTagGroups []*XTagGroup `json:"x-tagGroups,omitempty" yaml:"x-tagGroups,omitempty"`
}
// Components holds a set of reusable objects for different
// aspects of the specification.
type Components struct {
Schemas map[string]*SchemaOrRef `json:"schemas,omitempty" yaml:"schemas,omitempty"`
Responses map[string]*ResponseOrRef `json:"responses,omitempty" yaml:"responses,omitempty"`
Parameters map[string]*ParameterOrRef `json:"parameters,omitempty" yaml:"parameters,omitempty"`
Examples map[string]*ExampleOrRef `json:"examples,omitempty" yaml:"examples,omitempty"`
Headers map[string]*HeaderOrRef `json:"headers,omitempty" yaml:"headers,omitempty"`
SecuritySchemes map[string]*SecuritySchemeOrRef `json:"securitySchemes,omitempty" yaml:"securitySchemes,omitempty"`
}
// Info represents the metadata of an API.
type 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 *Contact `json:"contact,omitempty" yaml:"contact,omitempty"`
License *License `json:"license,omitempty" yaml:"license,omitempty"`
Version string `json:"version" yaml:"version"`
XLogo *XLogo `json:"x-logo,omitempty" yaml:"x-logo,omitempty"`
}
// Contact represents the the contact informations
// exposed for an API.
type Contact struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"`
URL string `json:"url,omitempty" yaml:"url,omitempty"`
Email string `json:"email,omitempty" yaml:"email,omitempty"`
}
// License represents the license informations
// exposed for an API.
type License struct {
Name string `json:"name" yaml:"name"`
URL string `json:"url,omitempty" yaml:"url,omitempty"`
}
// Server represents a server.
type Server struct {
URL string `json:"url" yaml:"url"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Variables map[string]*ServerVariable `json:"variables,omitempty" yaml:"variables,omitempty"`
}
// ServerVariable represents a server variable for server
// URL template substitution.
type ServerVariable struct {
Enum []string `json:"enum,omitempty" yaml:"enum,omitempty"`
Default string `json:"default" yaml:"default"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
}
// Paths represents the relative paths to the individual
// endpoints and their operations.
type Paths map[string]*PathItem
// PathItem describes the operations available on a single
// API path.
type PathItem struct {
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
GET *Operation `json:"get,omitempty" yaml:"get,omitempty"`
PUT *Operation `json:"put,omitempty" yaml:"put,omitempty"`
POST *Operation `json:"post,omitempty" yaml:"post,omitempty"`
DELETE *Operation `json:"delete,omitempty" yaml:"delete,omitempty"`
OPTIONS *Operation `json:"options,omitempty" yaml:"options,omitempty"`
HEAD *Operation `json:"head,omitempty" yaml:"head,omitempty"`
PATCH *Operation `json:"patch,omitempty" yaml:"patch,omitempty"`
TRACE *Operation `json:"trace,omitempty" yaml:"trace,omitempty"`
Servers []*Server `json:"servers,omitempty" yaml:"servers,omitempty"`
Parameters []*ParameterOrRef `json:"parameters,omitempty" yaml:"parameters,omitempty"`
}
// Reference is a simple object to allow referencing
// other components in the specification, internally and
// externally.
type Reference struct {
Ref string `json:"$ref" yaml:"$ref"`
}
// Parameter describes a single operation parameter.
type Parameter struct {
Name string `json:"name" yaml:"name"`
In string `json:"in" yaml:"in"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`
AllowEmptyValue bool `json:"allowEmptyValue,omitempty" yaml:"allowEmptyValue,omitempty"`
Schema *SchemaOrRef `json:"schema,omitempty" yaml:"schema,omitempty"`
Style string `json:"style,omitempty" yaml:"style,omitempty"`
Explode bool `json:"explode,omitempty" yaml:"explode,omitempty"`
}
// ParameterOrRef represents a Parameter that can be inlined
// or referenced in the API description.
type ParameterOrRef struct {
*Parameter
*Reference
}
// MarshalYAML implements yaml.Marshaler for ParameterOrRef.
func (por *ParameterOrRef) MarshalYAML() (interface{}, error) {
if por.Parameter != nil {
return por.Parameter, nil
}
return por.Reference, nil
}
// RequestBody represents a request body.
type RequestBody struct {
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Content map[string]*MediaType `json:"content" yaml:"content"`
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
}
// SchemaOrRef represents a Schema that can be inlined
// or referenced in the API description.
type SchemaOrRef struct {
*Schema
*Reference
}
// MarshalYAML implements yaml.Marshaler for SchemaOrRef.
func (sor *SchemaOrRef) MarshalYAML() (interface{}, error) {
if sor.Schema != nil {
return sor.Schema, nil
}
return sor.Reference, nil
}
// Schema represents the definition of input and output data
// types of the API.
type Schema struct {
// The following properties are taken from the JSON Schema
// definition but their definitions were adjusted to the
// OpenAPI Specification.
Type string `json:"type,omitempty" yaml:"type,omitempty"`
AllOf *SchemaOrRef `json:"allOf,omitempty" yaml:"allOf,omitempty"`
OneOf *SchemaOrRef `json:"oneOf,omitempty" yaml:"oneOf,omitempty"`
AnyOf *SchemaOrRef `json:"anyOf,omitempty" yaml:"anyOf,omitempty"`
Items *SchemaOrRef `json:"items,omitempty" yaml:"items,omitempty"`
Properties map[string]*SchemaOrRef `json:"properties,omitempty" yaml:"properties,omitempty"`
AdditionalProperties *SchemaOrRef `json:"additionalProperties,omitempty" yaml:"additionalProperties,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Format string `json:"format,omitempty" yaml:"format,omitempty"`
Default interface{} `json:"default,omitempty" yaml:"default,omitempty"`
Example interface{} `json:"example,omitempty" yaml:"example,omitempty"`
// The following properties are taken directly from the
// JSON Schema definition and follow the same specifications
Title string `json:"title,omitempty" yaml:"title,omitempty"`
MultipleOf int `json:"multipleOf,omitempty" yaml:"multipleOf,omitempty"`
Maximum int `json:"maximum,omitempty" yaml:"maximum,omitempty"`
ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty" yaml:"exclusiveMaximum,omitempty"`
Minimum int `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"`
MaxProperties int `json:"maxProperties,omitempty" yaml:"maxProperties,omitempty"`
MinProperties int `json:"minProperties,omitempty" yaml:"minProperties,omitempty"`
Required []string `json:"required,omitempty" yaml:"required,omitempty"`
Enum []interface{} `json:"enum,omitempty" yaml:"enum,omitempty"`
Nullable bool `json:"nullable,omitempty" yaml:"nullable,omitempty"`
Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`
}
// Operation describes an API operation on a path.
type Operation struct {
Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"`
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
ID string `json:"operationId,omitempty" yaml:"operationId,omitempty"`
Parameters []*ParameterOrRef `json:"parameters,omitempty" yaml:"parameters,omitempty"`
RequestBody *RequestBody `json:"requestBody,omitempty" yaml:"requestBody,omitempty"`
Responses Responses `json:"responses,omitempty" yaml:"responses,omitempty"`
Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`
Servers []*Server `json:"servers,omitempty" yaml:"servers,omitempty"`
Security []*SecurityRequirement `json:"security" yaml:"security"`
XCodeSamples []*XCodeSample `json:"x-codeSamples,omitempty" yaml:"x-codeSamples,omitempty"`
XInternal bool `json:"x-internal,omitempty" yaml:"x-internal,omitempty"`
}
// A workaround for missing omitnil functionality.
// Explicitely omit the Security field from marshaling when it is nil, but not when empty.
type operationNilOmitted struct {
Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"`
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
ID string `json:"operationId,omitempty" yaml:"operationId,omitempty"`
Parameters []*ParameterOrRef `json:"parameters,omitempty" yaml:"parameters,omitempty"`
RequestBody *RequestBody `json:"requestBody,omitempty" yaml:"requestBody,omitempty"`
Responses Responses `json:"responses,omitempty" yaml:"responses,omitempty"`
Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`
Servers []*Server `json:"servers,omitempty" yaml:"servers,omitempty"`
XCodeSamples []*XCodeSample `json:"x-codeSamples,omitempty" yaml:"x-codeSamples,omitempty"`
XInternal bool `json:"x-internal,omitempty" yaml:"x-internal,omitempty"`
}
// MarshalYAML implements yaml.Marshaler for Operation.
// Needed to marshall empty but non-null SecurityRequirements.
func (o *Operation) MarshalYAML() (interface{}, error) {
if o.Security == nil {
return omitOperationNilFields(o), nil
}
return o, nil
}
// MarshalJSON excludes empty but non-null SecurityRequirements.
func (o *Operation) MarshalJSON() ([]byte, error) {
if o.Security == nil {
return json.Marshal(omitOperationNilFields(o))
}
return json.Marshal(*o)
}
func omitOperationNilFields(o *Operation) *operationNilOmitted {
return &operationNilOmitted{
Tags: o.Tags,
Summary: o.Summary,
Description: o.Description,
ID: o.ID,
Parameters: o.Parameters,
RequestBody: o.RequestBody,
Responses: o.Responses,
Deprecated: o.Deprecated,
Servers: o.Servers,
XCodeSamples: o.XCodeSamples,
XInternal: o.XInternal,
}
}
// Responses represents a container for the expected responses
// of an opration. It maps a HTTP response code to the expected
// response.
type Responses map[string]*ResponseOrRef
// ResponseOrRef represents a Response that can be inlined
// or referenced in the API description.
type ResponseOrRef struct {
*Response
*Reference
}
// MarshalYAML implements yaml.Marshaler for ResponseOrRef.
func (ror *ResponseOrRef) MarshalYAML() (interface{}, error) {
if ror.Response != nil {
return ror.Response, nil
}
return ror.Reference, nil
}
// Response describes a single response from an API.
type Response struct {
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Headers map[string]*HeaderOrRef `json:"headers,omitempty" yaml:"headers,omitempty"`
Content map[string]*MediaTypeOrRef `json:"content,omitempty" yaml:"content,omitempty"`
}
// HeaderOrRef represents a Header that can be inlined
// or referenced in the API description.
type HeaderOrRef struct {
*Header
*Reference
}
// MarshalYAML implements yaml.Marshaler for HeaderOrRef.
func (hor *HeaderOrRef) MarshalYAML() (interface{}, error) {
if hor.Header != nil {
return hor.Header, nil
}
return hor.Reference, nil
}
// Header represents an HTTP header.
type Header struct {
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`
AllowEmptyValue bool `json:"allowEmptyValue,omitempty" yaml:"allowEmptyValue,omitempty"`
Schema *SchemaOrRef `json:"schema,omitempty" yaml:"schema,omitempty"`
}
// MediaTypeOrRef represents a MediaType that can be inlined
// or referenced in the API description.
type MediaTypeOrRef struct {
*MediaType
*Reference
}
// MarshalYAML implements yaml.Marshaler for MediaTypeOrRef.
func (mtor *MediaTypeOrRef) MarshalYAML() (interface{}, error) {
if mtor.MediaType != nil {
return mtor.MediaType, nil
}
return mtor.Reference, nil
}
// MediaType represents the type of a media.
type MediaType struct {
Schema *SchemaOrRef `json:"schema" yaml:"schema"`
Example interface{} `json:"example,omitempty" yaml:"example,omitempty"`
Examples map[string]*ExampleOrRef `json:"examples,omitempty" yaml:"examples,omitempty"`
Encoding map[string]*Encoding `json:"encoding,omitempty" yaml:"encoding,omitempty"`
}
// ExampleOrRef represents an Example that can be inlined
// or referenced in the API description.
type ExampleOrRef struct {
*Example
*Reference
}
// MarshalYAML implements yaml.Marshaler for ExampleOrRef.
func (eor *ExampleOrRef) MarshalYAML() (interface{}, error) {
if eor.Example != nil {
return eor.Example, nil
}
return eor.Reference, nil
}
// Example represents the example of a media type.
type Example struct {
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Value interface{} `json:"value,omitempty" yaml:"value,omitempty"`
ExternalValue string `json:"externalValue,omitempty" yaml:"externalValue,omitempty"`
}
// Encoding represents a single encoding definition
// applied to a single schema property.
type Encoding struct {
ContentType string `json:"contentType,omitempty" yaml:"contentType,omitempty"`
Headers map[string]*HeaderOrRef `json:"headers,omitempty" yaml:"headers,omitempty"`
Style string `json:"style,omitempty" yaml:"style,omitempty"`
Explode bool `json:"explode,omitempty" yaml:"explode,omitempty"`
AllowReserved bool `json:"allowReserved,omitempty" yaml:"allowReserved,omitempty"`
}
// Tag represents the metadata of a single tag.
type Tag struct {
Name string `json:"name" yaml:"name"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
}
// SecuritySchemeOrRef represents a SecurityScheme that can be inlined
// or referenced in the API description.
type SecuritySchemeOrRef struct {
*SecurityScheme
*Reference
}
// MarshalYAML implements yaml.Marshaler for SecuritySchemeOrRef.
func (sor *SecuritySchemeOrRef) MarshalYAML() (interface{}, error) {
if sor.SecurityScheme != nil {
return sor.SecurityScheme, nil
}
return sor.Reference, nil
}
// SecurityScheme represents a security scheme that can be used by an operation.
type SecurityScheme struct {
Type string `json:"type,omitempty" yaml:"type,omitempty"`
Scheme string `json:"scheme,omitempty" yaml:"scheme,omitempty"`
BearerFormat string `json:"bearerFormat,omitempty" yaml:"bearerFormat,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
In string `json:"in,omitempty" yaml:"in,omitempty"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
OpenIDConnectURL string `json:"openIdConnectUrl,omitempty" yaml:"openIdConnectUrl,omitempty"`
Flows *OAuthFlows `json:"flows,omitempty" yaml:"flows,omitempty"`
}
// OAuthFlows represents all the supported OAuth flows.
type OAuthFlows struct {
Implicit *OAuthFlow `json:"implicit,omitempty" yaml:"implicit,omitempty"`
Password *OAuthFlow `json:"password,omitempty" yaml:"password,omitempty"`
ClientCredentials *OAuthFlow `json:"clientCredentials,omitempty" yaml:"clientCredentials,omitempty"`
AuthorizationCode *OAuthFlow `json:"authorizationCode,omitempty" yaml:"authorizationCode,omitempty"`
}
// OAuthFlow represents an OAuth security scheme.
type OAuthFlow struct {
AuthorizationURL string `json:"authorizationUrl,omitempty" yaml:"authorizationUrl,omitempty"`
TokenURL string `json:"tokenUrl,omitempty" yaml:"tokenUrl,omitempty"`
RefreshURL string `json:"refreshUrl,omitempty" yaml:"refreshUrl,omitempty"`
Scopes map[string]string `json:"scopes,omitempty" yaml:"scopes,omitempty"`
}
// MarshalYAML implements yaml.Marshaler for OAuthFlow.
func (f OAuthFlow) MarshalYAML() ([]byte, error) {
type flow OAuthFlow
if f.Scopes == nil {
// The field is REQUIRED and MAY be empty according to the spec.
f.Scopes = map[string]string{}
}
return json.Marshal(flow(f))
}
// SecurityRequirement represents the security object in the API specification.
type SecurityRequirement map[string][]string
// XLogo represents the information about the x-logo extension.
// See: https://github.com/Redocly/redoc/blob/master/docs/redoc-vendor-extensions.md#x-logo
type XLogo struct {
URL string `json:"url,omitempty" yaml:"url,omitempty"`
BackgroundColor string `json:"backgroundColor,omitempty" yaml:"backgroundColor,omitempty"`
AltText string `json:"altText,omitempty" yaml:"altText,omitempty"`
Href string `json:"href,omitempty" yaml:"href,omitempty"`
}
// XTagGroup represents the information about the x-tagGroups extension.
// See: https://github.com/Redocly/redoc/blob/master/docs/redoc-vendor-extensions.md#x-taggroups
type XTagGroup struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"`
}
// XCodeSample represents the information about the x-codeSample extension.
// See: https://github.com/Redocly/redoc/blob/master/docs/redoc-vendor-extensions.md#x-codesamples
type XCodeSample struct {
Lang string `json:"lang,omitempty" yaml:"lang,omitempty"`
Label string `json:"label,omitempty" yaml:"label,omitempty"`
Source string `json:"source,omitempty" yaml:"source,omitempty"`
}