1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package simplepetstore
16
17 import (
18 "encoding/json"
19 "net/http"
20 "sync"
21 "sync/atomic"
22
23 "github.com/go-openapi/errors"
24 "github.com/go-openapi/loads"
25
26 "github.com/go-openapi/runtime"
27 "github.com/go-openapi/runtime/middleware"
28 "github.com/go-openapi/runtime/middleware/untyped"
29 )
30
31
32 func NewPetstore() (http.Handler, error) {
33 spec, err := loads.Analyzed(json.RawMessage([]byte(swaggerJSON)), "")
34 if err != nil {
35 return nil, err
36 }
37 api := untyped.NewAPI(spec)
38
39 api.RegisterOperation("get", "/pets", getAllPets)
40 api.RegisterOperation("post", "/pets", createPet)
41 api.RegisterOperation("delete", "/pets/{id}", deletePet)
42 api.RegisterOperation("get", "/pets/{id}", getPetByID)
43
44 return middleware.Serve(spec, api), nil
45 }
46
47 var getAllPets = runtime.OperationHandlerFunc(func(_ interface{}) (interface{}, error) {
48 return pets, nil
49 })
50
51 var createPet = runtime.OperationHandlerFunc(func(data interface{}) (interface{}, error) {
52 body := data.(map[string]interface{})["pet"].(map[string]interface{})
53 return addPet(Pet{
54 Name: body["name"].(string),
55 Status: body["status"].(string),
56 }), nil
57 })
58
59 var deletePet = runtime.OperationHandlerFunc(func(data interface{}) (interface{}, error) {
60 id := data.(map[string]interface{})["id"].(int64)
61 removePet(id)
62 return map[string]interface{}{}, nil
63 })
64
65 var getPetByID = runtime.OperationHandlerFunc(func(data interface{}) (interface{}, error) {
66 id := data.(map[string]interface{})["id"].(int64)
67 return petByID(id)
68 })
69
70
71 type Tag struct {
72 ID int64
73 Name string
74 }
75
76
77 type Pet struct {
78 ID int64 `json:"id"`
79 Name string `json:"name"`
80 PhotoURLs []string `json:"photoUrls,omitempty"`
81 Status string `json:"status,omitempty"`
82 Tags []Tag `json:"tags,omitempty"`
83 }
84
85 var pets = []Pet{
86 {1, "Dog", []string{}, "available", nil},
87 {2, "Cat", []string{}, "pending", nil},
88 }
89
90 var petsLock = &sync.Mutex{}
91 var lastPetID int64 = 2
92
93 func newPetID() int64 {
94 return atomic.AddInt64(&lastPetID, 1)
95 }
96
97 func addPet(pet Pet) Pet {
98 petsLock.Lock()
99 defer petsLock.Unlock()
100 pet.ID = newPetID()
101 pets = append(pets, pet)
102 return pet
103 }
104
105 func removePet(id int64) {
106 petsLock.Lock()
107 defer petsLock.Unlock()
108 var newPets []Pet
109 for _, pet := range pets {
110 if pet.ID != id {
111 newPets = append(newPets, pet)
112 }
113 }
114 pets = newPets
115 }
116
117 func petByID(id int64) (*Pet, error) {
118 for _, pet := range pets {
119 if pet.ID == id {
120 return &pet, nil
121 }
122 }
123 return nil, errors.NotFound("not found: pet %d", id)
124 }
125
126 var swaggerJSON = `{
127 "swagger": "2.0",
128 "info": {
129 "version": "1.0.0",
130 "title": "Swagger Petstore",
131 "description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification",
132 "termsOfService": "http://helloreverb.com/terms/",
133 "contact": {
134 "name": "Wordnik API Team"
135 },
136 "license": {
137 "name": "MIT"
138 }
139 },
140 "host": "localhost:8344",
141 "basePath": "/api",
142 "schemes": [
143 "http"
144 ],
145 "consumes": [
146 "application/json"
147 ],
148 "produces": [
149 "application/json"
150 ],
151 "paths": {
152 "/pets": {
153 "get": {
154 "description": "Returns all pets from the system that the user has access to",
155 "operationId": "findPets",
156 "produces": [
157 "application/json",
158 "application/xml",
159 "text/xml",
160 "text/html"
161 ],
162 "parameters": [
163 {
164 "name": "tags",
165 "in": "query",
166 "description": "tags to filter by",
167 "required": false,
168 "type": "array",
169 "items": {
170 "type": "string"
171 },
172 "collectionFormat": "csv"
173 },
174 {
175 "name": "limit",
176 "in": "query",
177 "description": "maximum number of results to return",
178 "required": false,
179 "type": "integer",
180 "format": "int32"
181 }
182 ],
183 "responses": {
184 "200": {
185 "description": "pet response",
186 "schema": {
187 "type": "array",
188 "items": {
189 "$ref": "#/definitions/pet"
190 }
191 }
192 },
193 "default": {
194 "description": "unexpected error",
195 "schema": {
196 "$ref": "#/definitions/errorModel"
197 }
198 }
199 }
200 },
201 "post": {
202 "description": "Creates a new pet in the store. Duplicates are allowed",
203 "operationId": "addPet",
204 "produces": [
205 "application/json"
206 ],
207 "parameters": [
208 {
209 "name": "pet",
210 "in": "body",
211 "description": "Pet to add to the store",
212 "required": true,
213 "schema": {
214 "$ref": "#/definitions/petInput"
215 }
216 }
217 ],
218 "responses": {
219 "200": {
220 "description": "pet response",
221 "schema": {
222 "$ref": "#/definitions/pet"
223 }
224 },
225 "default": {
226 "description": "unexpected error",
227 "schema": {
228 "$ref": "#/definitions/errorModel"
229 }
230 }
231 }
232 }
233 },
234 "/pets/{id}": {
235 "get": {
236 "description": "Returns a user based on a single ID, if the user does not have access to the pet",
237 "operationId": "findPetById",
238 "produces": [
239 "application/json",
240 "application/xml",
241 "text/xml",
242 "text/html"
243 ],
244 "parameters": [
245 {
246 "name": "id",
247 "in": "path",
248 "description": "ID of pet to fetch",
249 "required": true,
250 "type": "integer",
251 "format": "int64"
252 }
253 ],
254 "responses": {
255 "200": {
256 "description": "pet response",
257 "schema": {
258 "$ref": "#/definitions/pet"
259 }
260 },
261 "default": {
262 "description": "unexpected error",
263 "schema": {
264 "$ref": "#/definitions/errorModel"
265 }
266 }
267 }
268 },
269 "delete": {
270 "description": "deletes a single pet based on the ID supplied",
271 "operationId": "deletePet",
272 "parameters": [
273 {
274 "name": "id",
275 "in": "path",
276 "description": "ID of pet to delete",
277 "required": true,
278 "type": "integer",
279 "format": "int64"
280 }
281 ],
282 "responses": {
283 "204": {
284 "description": "pet deleted"
285 },
286 "default": {
287 "description": "unexpected error",
288 "schema": {
289 "$ref": "#/definitions/errorModel"
290 }
291 }
292 }
293 }
294 }
295 },
296 "definitions": {
297 "pet": {
298 "required": [
299 "name",
300 "status"
301 ],
302 "properties": {
303 "id": {
304 "type": "integer",
305 "format": "int64"
306 },
307 "name": {
308 "type": "string"
309 },
310 "status": {
311 "type": "string"
312 },
313 "tags": {
314 "type": "array",
315 "items": {
316 "type": "string"
317 }
318 }
319 }
320 },
321 "petInput": {
322 "allOf": [
323 {
324 "$ref": "#/definitions/pet"
325 },
326 {
327 "properties": {
328 "id": {
329 "type": "integer",
330 "format": "int64"
331 }
332 }
333 }
334 ]
335 },
336 "errorModel": {
337 "required": [
338 "code",
339 "message"
340 ],
341 "properties": {
342 "code": {
343 "type": "integer",
344 "format": "int32"
345 },
346 "message": {
347 "type": "string"
348 }
349 }
350 }
351 }
352 }`
353
View as plain text