-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathpath.go
executable file
·314 lines (285 loc) · 6.79 KB
/
path.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
package swaggos
import (
"strings"
"github.com/go-openapi/spec"
)
const applicationJSON = "application/json"
const (
inForm = iota + 1
inBody
)
const (
_InPath = "path"
_InQuery = "query"
_InBody = "body"
_InHeader = "header"
_InForm = "formData"
)
// Path defines a router spec
type Path struct {
prop spec.OperationProps
response map[int]spec.Response
paramDeep int
doc *Swaggos
}
func newPath(d *Swaggos) *Path {
path := new(Path)
path.response = make(map[int]spec.Response)
path.paramDeep = 0
path.doc = d
return path
}
// parsePath parse the path if it contains path param
func (p *Path) parsePath(path string) {
arr := strings.Split(path, "/")
for _, a := range arr {
if a == "" {
continue
}
if a[0] == '{' && a[len(a)-1] == '}' {
name := a[1 : len(a)-1]
if name == "" {
continue
}
p.prop.Parameters = append(p.prop.Parameters, spec.Parameter{
SimpleSchema: spec.SimpleSchema{
Type: _String,
},
ParamProps: spec.ParamProps{
Name: name,
In: _InPath,
Required: true,
},
})
}
}
}
// Tag set the path tag
func (p *Path) Tag(v ...string) *Path {
p.prop.Tags = v
return p
}
// Summary create summary of the path
func (p *Path) Summary(v string) *Path {
p.prop.Summary = v
return p
}
// Description create description of the path
func (p *Path) Description(s string) *Path {
p.prop.Description = s
return p
}
// ContentType create request and response Content-Type
func (p *Path) ContentType(req, resp string) {
p.prop.Consumes = []string{req}
p.prop.Produces = []string{resp}
}
// Form create form Params
func (p *Path) Form(name string, attribute Attribute) *Path {
if p.paramDeep == inBody {
panic("body and form can't be set at same time")
}
p.paramDeep = inForm
p.prop.Parameters = append(p.prop.Parameters, spec.Parameter{
SimpleSchema: spec.SimpleSchema{
Type: string(attribute.Type),
Format: string(attribute.Format),
Default: attribute.Default,
Example: attribute.Example,
},
ParamProps: spec.ParamProps{
Description: attribute.Description,
Name: name,
In: _InForm,
Required: attribute.Required,
},
})
return p
}
// FormObject create form object params
func (p *Path) FormObject(v interface{}) *Path {
if p.paramDeep == inBody {
panic("body and form can't be set at same time")
}
p.paramDeep = inForm
ref := p.doc.buildSchema(v)
for name, sch := range ref.SchemaProps.Properties {
var param = spec.Parameter{
SimpleSchema: spec.SimpleSchema{},
ParamProps: spec.ParamProps{
Name: name,
In: _InForm,
Schema: &sch,
},
}
p.prop.Parameters = append(p.prop.Parameters, param)
}
return p
}
// addParam add params to the path
func (p *Path) addParam(params ...spec.Parameter) *Path {
for _, v := range params {
p.prop.Parameters = append(p.prop.Parameters, v)
}
return p
}
// FormFile add file param to the path
func (p *Path) FormFile(name string, attribute Attribute) *Path {
if p.paramDeep == inBody {
panic("body and form can't be set at same time")
}
p.paramDeep = inForm
p.prop.Parameters = append(p.prop.Parameters, spec.Parameter{
SimpleSchema: spec.SimpleSchema{
Type: _File,
},
ParamProps: spec.ParamProps{
Description: attribute.Description,
Name: name,
In: _InForm,
Required: attribute.Required,
},
})
return p
}
// Query create a query param to path
func (p *Path) Query(name string, attribute Attribute) *Path {
p.prop.Parameters = append(p.prop.Parameters, spec.Parameter{
SimpleSchema: spec.SimpleSchema{
Type: string(attribute.Type),
Format: string(attribute.Format),
Default: attribute.Default,
Example: attribute.Example,
},
ParamProps: spec.ParamProps{
Description: attribute.Description,
Name: name,
In: _InQuery,
Required: attribute.Required,
},
})
return p
}
// QueryObject parse an object to query
func (p *Path) QueryObject(v interface{}) *Path {
ref := p.doc.buildSchema(v)
for name, sch := range ref.SchemaProps.Properties {
var param = spec.Parameter{
SimpleSchema: spec.SimpleSchema{},
ParamProps: spec.ParamProps{
Name: name,
In: _InQuery,
Schema: &sch,
},
}
p.prop.Parameters = append(p.prop.Parameters, param)
}
return p
}
// Header create a header to path
func (p *Path) Header(name string, attribute Attribute) *Path {
p.prop.Parameters = append(p.prop.Parameters, spec.Parameter{
SimpleSchema: spec.SimpleSchema{
Type: string(attribute.Type),
Format: string(attribute.Format),
Default: attribute.Default,
Example: attribute.Example,
},
ParamProps: spec.ParamProps{
Description: attribute.Description,
Name: name,
In: _InHeader,
Required: attribute.Required,
},
})
return p
}
// Body create body to path
func (p *Path) Body(v interface{}) *Path {
if p.paramDeep == inForm {
panic("body and form can't be set at same time")
}
p.paramDeep = inBody
ref := p.doc.Define(v)
p.prop.Parameters = append(p.prop.Parameters, spec.Parameter{
ParamProps: spec.ParamProps{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Ref: ref,
},
},
In: _InBody,
Name: _InBody,
},
})
return p
}
// JSON create json response to path
func (p *Path) JSON(v interface{}) *Path {
ref := p.doc.Define(v)
p.addResponse(200, ref, v)
return p
}
// BadRequest serve BadRequest to path
func (p *Path) BadRequest(v interface{}) *Path {
ref := p.doc.Define(v)
p.addResponse(400, ref, v)
return p
}
// ServerError serve 500 to path
func (p *Path) ServerError(v interface{}) *Path {
ref := p.doc.Define(v)
p.addResponse(500, ref, v)
return p
}
// Forbidden create 403 to path
func (p *Path) Forbidden(v interface{}) *Path {
ref := p.doc.Define(v)
p.addResponse(403, ref, v)
return p
}
// UnAuthorization create 401 to path
func (p *Path) UnAuthorization(v interface{}) *Path {
ref := p.doc.Define(v)
p.addResponse(401, ref, v)
return p
}
// addResponse add response to path
func (p *Path) addResponse(status int, ref spec.Ref, example interface{}) {
p.response[status] = spec.Response{
ResponseProps: spec.ResponseProps{
Description: "json response",
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Ref: ref,
},
},
Examples: map[string]interface{}{
applicationJSON: example,
},
},
}
}
// build build the swagger operation
func (p *Path) build() *spec.Operation {
var (
defaultResponse *spec.Response
)
for code, resp := range p.doc.response {
if _, ok := p.response[code]; !ok {
p.response[code] = resp
}
}
if resp, ok := p.response[200]; ok {
defaultResponse = &resp
}
p.prop.Responses = &spec.Responses{
ResponsesProps: spec.ResponsesProps{
Default: defaultResponse,
StatusCodeResponses: p.response,
},
}
return &spec.Operation{
OperationProps: p.prop,
}
}