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