blob: 71aee1e80638a2d82f78941efa8749c98d591b5e [file] [log] [blame]
Matthias Andreas Benkard832a54e2019-01-29 09:27:38 +01001// Copyright 2015 go-swagger maintainers
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package spec
16
17import (
18 "encoding/json"
19 "strings"
20
21 "github.com/go-openapi/jsonpointer"
22 "github.com/go-openapi/swag"
23)
24
25// QueryParam creates a query parameter
26func QueryParam(name string) *Parameter {
27 return &Parameter{ParamProps: ParamProps{Name: name, In: "query"}}
28}
29
30// HeaderParam creates a header parameter, this is always required by default
31func HeaderParam(name string) *Parameter {
32 return &Parameter{ParamProps: ParamProps{Name: name, In: "header", Required: true}}
33}
34
35// PathParam creates a path parameter, this is always required
36func PathParam(name string) *Parameter {
37 return &Parameter{ParamProps: ParamProps{Name: name, In: "path", Required: true}}
38}
39
40// BodyParam creates a body parameter
41func BodyParam(name string, schema *Schema) *Parameter {
42 return &Parameter{ParamProps: ParamProps{Name: name, In: "body", Schema: schema}, SimpleSchema: SimpleSchema{Type: "object"}}
43}
44
45// FormDataParam creates a body parameter
46func FormDataParam(name string) *Parameter {
47 return &Parameter{ParamProps: ParamProps{Name: name, In: "formData"}}
48}
49
50// FileParam creates a body parameter
51func FileParam(name string) *Parameter {
52 return &Parameter{ParamProps: ParamProps{Name: name, In: "formData"}, SimpleSchema: SimpleSchema{Type: "file"}}
53}
54
55// SimpleArrayParam creates a param for a simple array (string, int, date etc)
56func SimpleArrayParam(name, tpe, fmt string) *Parameter {
57 return &Parameter{ParamProps: ParamProps{Name: name}, SimpleSchema: SimpleSchema{Type: "array", CollectionFormat: "csv", Items: &Items{SimpleSchema: SimpleSchema{Type: "string", Format: fmt}}}}
58}
59
60// ParamRef creates a parameter that's a json reference
61func ParamRef(uri string) *Parameter {
62 p := new(Parameter)
63 p.Ref = MustCreateRef(uri)
64 return p
65}
66
67type ParamProps struct {
68 Description string `json:"description,omitempty"`
69 Name string `json:"name,omitempty"`
70 In string `json:"in,omitempty"`
71 Required bool `json:"required,omitempty"`
72 Schema *Schema `json:"schema,omitempty"` // when in == "body"
73 AllowEmptyValue bool `json:"allowEmptyValue,omitempty"` // when in == "query" || "formData"
74}
75
76// Parameter a unique parameter is defined by a combination of a [name](#parameterName) and [location](#parameterIn).
77//
78// There are five possible parameter types.
79// * Path - Used together with [Path Templating](#pathTemplating), where the parameter value is actually part of the operation's URL. This does not include the host or base path of the API. For example, in `/items/{itemId}`, the path parameter is `itemId`.
80// * Query - Parameters that are appended to the URL. For example, in `/items?id=###`, the query parameter is `id`.
81// * Header - Custom headers that are expected as part of the request.
82// * Body - The payload that's appended to the HTTP request. Since there can only be one payload, there can only be *one* body parameter. The name of the body parameter has no effect on the parameter itself and is used for documentation purposes only. Since Form parameters are also in the payload, body and form parameters cannot exist together for the same operation.
83// * Form - Used to describe the payload of an HTTP request when either `application/x-www-form-urlencoded` or `multipart/form-data` are used as the content type of the request (in Swagger's definition, the [`consumes`](#operationConsumes) property of an operation). This is the only parameter type that can be used to send files, thus supporting the `file` type. Since form parameters are sent in the payload, they cannot be declared together with a body parameter for the same operation. Form parameters have a different format based on the content-type used (for further details, consult http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4):
84// * `application/x-www-form-urlencoded` - Similar to the format of Query parameters but as a payload. For example, `foo=1&bar=swagger` - both `foo` and `bar` are form parameters. This is normally used for simple parameters that are being transferred.
85// * `multipart/form-data` - each parameter takes a section in the payload with an internal header. For example, for the header `Content-Disposition: form-data; name="submit-name"` the name of the parameter is `submit-name`. This type of form parameters is more commonly used for file transfers.
86//
87// For more information: http://goo.gl/8us55a#parameterObject
88type Parameter struct {
89 Refable
90 CommonValidations
91 SimpleSchema
92 VendorExtensible
93 ParamProps
94}
95
96// JSONLookup look up a value by the json property name
97func (p Parameter) JSONLookup(token string) (interface{}, error) {
98 if ex, ok := p.Extensions[token]; ok {
99 return &ex, nil
100 }
101 if token == "$ref" {
102 return &p.Ref, nil
103 }
104
105 r, _, err := jsonpointer.GetForToken(p.CommonValidations, token)
106 if err != nil && !strings.HasPrefix(err.Error(), "object has no field") {
107 return nil, err
108 }
109 if r != nil {
110 return r, nil
111 }
112 r, _, err = jsonpointer.GetForToken(p.SimpleSchema, token)
113 if err != nil && !strings.HasPrefix(err.Error(), "object has no field") {
114 return nil, err
115 }
116 if r != nil {
117 return r, nil
118 }
119 r, _, err = jsonpointer.GetForToken(p.ParamProps, token)
120 return r, err
121}
122
123// WithDescription a fluent builder method for the description of the parameter
124func (p *Parameter) WithDescription(description string) *Parameter {
125 p.Description = description
126 return p
127}
128
129// Named a fluent builder method to override the name of the parameter
130func (p *Parameter) Named(name string) *Parameter {
131 p.Name = name
132 return p
133}
134
135// WithLocation a fluent builder method to override the location of the parameter
136func (p *Parameter) WithLocation(in string) *Parameter {
137 p.In = in
138 return p
139}
140
141// Typed a fluent builder method for the type of the parameter value
142func (p *Parameter) Typed(tpe, format string) *Parameter {
143 p.Type = tpe
144 p.Format = format
145 return p
146}
147
148// CollectionOf a fluent builder method for an array parameter
149func (p *Parameter) CollectionOf(items *Items, format string) *Parameter {
150 p.Type = "array"
151 p.Items = items
152 p.CollectionFormat = format
153 return p
154}
155
156// WithDefault sets the default value on this parameter
157func (p *Parameter) WithDefault(defaultValue interface{}) *Parameter {
158 p.AsOptional() // with default implies optional
159 p.Default = defaultValue
160 return p
161}
162
163// AllowsEmptyValues flags this parameter as being ok with empty values
164func (p *Parameter) AllowsEmptyValues() *Parameter {
165 p.AllowEmptyValue = true
166 return p
167}
168
169// NoEmptyValues flags this parameter as not liking empty values
170func (p *Parameter) NoEmptyValues() *Parameter {
171 p.AllowEmptyValue = false
172 return p
173}
174
175// AsOptional flags this parameter as optional
176func (p *Parameter) AsOptional() *Parameter {
177 p.Required = false
178 return p
179}
180
181// AsRequired flags this parameter as required
182func (p *Parameter) AsRequired() *Parameter {
183 if p.Default != nil { // with a default required makes no sense
184 return p
185 }
186 p.Required = true
187 return p
188}
189
190// WithMaxLength sets a max length value
191func (p *Parameter) WithMaxLength(max int64) *Parameter {
192 p.MaxLength = &max
193 return p
194}
195
196// WithMinLength sets a min length value
197func (p *Parameter) WithMinLength(min int64) *Parameter {
198 p.MinLength = &min
199 return p
200}
201
202// WithPattern sets a pattern value
203func (p *Parameter) WithPattern(pattern string) *Parameter {
204 p.Pattern = pattern
205 return p
206}
207
208// WithMultipleOf sets a multiple of value
209func (p *Parameter) WithMultipleOf(number float64) *Parameter {
210 p.MultipleOf = &number
211 return p
212}
213
214// WithMaximum sets a maximum number value
215func (p *Parameter) WithMaximum(max float64, exclusive bool) *Parameter {
216 p.Maximum = &max
217 p.ExclusiveMaximum = exclusive
218 return p
219}
220
221// WithMinimum sets a minimum number value
222func (p *Parameter) WithMinimum(min float64, exclusive bool) *Parameter {
223 p.Minimum = &min
224 p.ExclusiveMinimum = exclusive
225 return p
226}
227
228// WithEnum sets a the enum values (replace)
229func (p *Parameter) WithEnum(values ...interface{}) *Parameter {
230 p.Enum = append([]interface{}{}, values...)
231 return p
232}
233
234// WithMaxItems sets the max items
235func (p *Parameter) WithMaxItems(size int64) *Parameter {
236 p.MaxItems = &size
237 return p
238}
239
240// WithMinItems sets the min items
241func (p *Parameter) WithMinItems(size int64) *Parameter {
242 p.MinItems = &size
243 return p
244}
245
246// UniqueValues dictates that this array can only have unique items
247func (p *Parameter) UniqueValues() *Parameter {
248 p.UniqueItems = true
249 return p
250}
251
252// AllowDuplicates this array can have duplicates
253func (p *Parameter) AllowDuplicates() *Parameter {
254 p.UniqueItems = false
255 return p
256}
257
258// UnmarshalJSON hydrates this items instance with the data from JSON
259func (p *Parameter) UnmarshalJSON(data []byte) error {
260 if err := json.Unmarshal(data, &p.CommonValidations); err != nil {
261 return err
262 }
263 if err := json.Unmarshal(data, &p.Refable); err != nil {
264 return err
265 }
266 if err := json.Unmarshal(data, &p.SimpleSchema); err != nil {
267 return err
268 }
269 if err := json.Unmarshal(data, &p.VendorExtensible); err != nil {
270 return err
271 }
272 if err := json.Unmarshal(data, &p.ParamProps); err != nil {
273 return err
274 }
275 return nil
276}
277
278// MarshalJSON converts this items object to JSON
279func (p Parameter) MarshalJSON() ([]byte, error) {
280 b1, err := json.Marshal(p.CommonValidations)
281 if err != nil {
282 return nil, err
283 }
284 b2, err := json.Marshal(p.SimpleSchema)
285 if err != nil {
286 return nil, err
287 }
288 b3, err := json.Marshal(p.Refable)
289 if err != nil {
290 return nil, err
291 }
292 b4, err := json.Marshal(p.VendorExtensible)
293 if err != nil {
294 return nil, err
295 }
296 b5, err := json.Marshal(p.ParamProps)
297 if err != nil {
298 return nil, err
299 }
300 return swag.ConcatJSON(b3, b1, b2, b4, b5), nil
301}