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  }`