@@ -21,14 +21,6 @@ import Test.Hspec hiding (example)
2121
2222spec :: Spec
2323spec = do
24− describe "host" $ do
25− it "can decode the host port" $ do
26− let h = Just $ Host "localhost" (Just (fromInteger 8000))
27− swagger :: Swagger
28− swagger = swaggerExample
29− & host .~ h
30− parsed :: Swagger = either error id $ eitherDecode' $ encode swagger
31− parsed ^. host `shouldBe` h
3224 describe "License Object" $ licenseExample <=> licenseExampleJSON
3325 describe "Contact Object" $ contactExample <=> contactExampleJSON
3426 describe "Info Object" $ infoExample <=> infoExampleJSON
@@ -48,9 +40,11 @@ spec = do
4840 describe "Swagger Object" $ do
4941 context "Example with no paths" $ emptyPathsFieldExample <=> emptyPathsFieldExampleJSON
5042 context "Todo Example" $ swaggerExample <=> swaggerExampleJSON
51− context "PetStore Example" $
43+ context "PetStore Example" $ do
5244 it "decodes successfully" $ do
5345 fromJSON petstoreExampleJSON `shouldSatisfy` (\x -> case x of Success (_ :: Swagger) -> True; _ -> False)
46+ it "roundtrips: fmap toJSON . fromJSON" $ do
47+ (toJSON :: Swagger -> Value) <$> fromJSON petstoreExampleJSON `shouldBe` Success petstoreExampleJSON
5448
5549main :: IO ()
5650main = hspec spec
@@ -133,34 +127,23 @@ operationExample = mempty
133127 & summary ?~ "Updates a pet in the store with form data"
134128 & description ?~ ""
135129 & operationId ?~ "updatePetWithForm"
136− & consumes ?~ MimeList ["application/x-www-form-urlencoded"]
137− & produces ?~ MimeList ["application/json", "application/xml"]
138− & parameters .~ map Inline
139− [ mempty
140− & name .~ "petId"
141− & description ?~ "ID of pet that needs to be updated"
142− & required ?~ True
143− & schema .~ ParamOther (stringSchema ParamPath)
144− , mempty
145− & name .~ "name"
146− & description ?~ "Updated name of the pet"
147− & required ?~ False
148− & schema .~ ParamOther (stringSchema ParamFormData)
149− , mempty
150− & name .~ "status"
151− & description ?~ "Updated status of the pet"
152− & required ?~ False
153− & schema .~ ParamOther (stringSchema ParamFormData)
154− ]
155−
130+ & parameters .~ [Inline (mempty
131+ & name .~ "petId"
132+ & description ?~ "ID of pet that needs to be updated"
133+ & required ?~ True
134+ & in_ .~ ParamPath
135+ & schema ?~ Inline (mempty & type_ ?~ SwaggerString))]
136+ & requestBody ?~ Inline (
137+ mempty & content . at "application/x-www-form-urlencoded" ?~ (mempty & schema ?~ (Inline (mempty
138+ & properties . at "petId" ?~ Inline (mempty
139+ & description ?~ "Updated name of the pet"
140+ & type_ ?~ SwaggerString)
141+ & properties . at "status" ?~ Inline (mempty
142+ & description ?~ "Updated status of the pet"
143+ & type_ ?~ SwaggerString)))))
156144 & at 200 ?~ "Pet updated."
157145 & at 405 ?~ "Invalid input"
158146 & security .~ [SecurityRequirement [("petstore_auth", ["write:pets", "read:pets"])]]
159− where
160− stringSchema :: ParamLocation -> ParamOtherSchema
161− stringSchema loc = mempty
162− & in_ .~ loc
163− & type_ ?~ SwaggerString
164147
165148operationExampleJSON :: Value
166149operationExampleJSON = [aesonQQ|
@@ -171,36 +154,35 @@ operationExampleJSON = [aesonQQ|
171154 "summary": "Updates a pet in the store with form data",
172155 "description": "",
173156 "operationId": "updatePetWithForm",
174− "consumes": [
175− "application/x-www-form-urlencoded"
176− ],
177− "produces": [
178− "application/json",
179− "application/xml"
180− ],
181157 "parameters": [
182158 {
183− "name": "petId",
184− "in": "path",
185− "description": "ID of pet that needs to be updated",
186159 "required": true,
187− "type": "string"
188− },
189− {
190− "name": "name",
191− "in": "formData",
192− "description": "Updated name of the pet",
193− "required": false,
194− "type": "string"
195− },
196− {
197− "name": "status",
198− "in": "formData",
199− "description": "Updated status of the pet",
200− "required": false,
201− "type": "string"
160+ "schema": {
161+ "type": "string"
162+ },
163+ "in": "path",
164+ "name": "petId",
165+ "description": "ID of pet that needs to be updated"
202166 }
203167 ],
168+ "requestBody": {
169+ "content": {
170+ "application/x-www-form-urlencoded": {
171+ "schema": {
172+ "properties": {
173+ "petId": {
174+ "type": "string",
175+ "description": "Updated name of the pet"
176+ },
177+ "status": {
178+ "type": "string",
179+ "description": "Updated status of the pet"
180+ }
181+ }
182+ }
183+ }
184+ }
185+ },
204186 "responses": {
205187 "200": {
206188 "description": "Pet updated."
@@ -251,24 +233,21 @@ schemaSimpleModelExample = mempty
251233
252234schemaSimpleModelExampleJSON :: Value
253235schemaSimpleModelExampleJSON = [aesonQQ|
254−{
255− "type": "object",
256− "required": [
257− "name"
258− ],
236+{ "required": [ "name" ],
259237 "properties": {
260238 "name": {
261239 "type": "string"
262240 },
263241 "address": {
264− "$ref": "#/definitions/Address"
242+ "$ref": "#/components/schemas/Address"
265243 },
266244 "age": {
267− "type": "integer",
268245 "format": "int32",
269− "minimum": 0
246+ "minimum": 0,
247+ "type": "integer"
270248 }
271− }
249+ },
250+ "type": "object"
272251}
273252|]
274253
@@ -401,16 +380,16 @@ paramsDefinitionExample =
401380 & name .~ "skip"
402381 & description ?~ "number of items to skip"
403382 & required ?~ True
404− & schema .~ ParamOther (mempty
405− & in_ .~ ParamQuery
383+ & in_ .~ ParamQuery
384+ & schema ?~ Inline (mempty
406385 & type_ ?~ SwaggerInteger
407386 & format ?~ "int32" ))
408387 , ("limitParam", mempty
409388 & name .~ "limit"
410389 & description ?~ "max records to return"
411390 & required ?~ True
412− & schema .~ ParamOther (mempty
413− & in_ .~ ParamQuery
391+ & in_ .~ ParamQuery
392+ & schema ?~ Inline (mempty
414393 & type_ ?~ SwaggerInteger
415394 & format ?~ "int32" )) ]
416395
@@ -422,16 +401,20 @@ paramsDefinitionExampleJSON = [aesonQQ|
422401 "in": "query",
423402 "description": "number of items to skip",
424403 "required": true,
425− "type": "integer",
426− "format": "int32"
404+ "schema": {
405+ "type": "integer",
406+ "format": "int32"
407+ }
427408 },
428409 "limitParam": {
429410 "name": "limit",
430411 "in": "query",
431412 "description": "max records to return",
432413 "required": true,
433− "type": "integer",
434− "format": "int32"
414+ "schema": {
415+ "type": "integer",
416+ "format": "int32"
417+ }
435418 }
436419}
437420|]
@@ -467,39 +450,45 @@ securityDefinitionsExample = SecurityDefinitions
467450 { _securitySchemeType = SecuritySchemeApiKey (ApiKeyParams "api_key" ApiKeyHeader)
468451 , _securitySchemeDescription = Nothing })
469452 , ("petstore_auth", SecurityScheme
470− { _securitySchemeType = SecuritySchemeOAuth2 (OAuth2Params
471− { _oauth2Flow = OAuth2Implicit "http://swagger.io/api/oauth/dialog"
472− , _oauth2Scopes =
473− [ ("write:pets", "modify pets in your account")
474− , ("read:pets", "read your pets") ] } )
453+ { _securitySchemeType = SecuritySchemeOAuth2 (mempty & implicit ?~ OAuth2Flow
454+ { _oAuth2Params = OAuth2ImplicitFlow "http://swagger.io/api/oauth/dialog"
455+ , _oAath2RefreshUrl = Nothing
456+ , _oAuth2Scopes =
457+ [ ("write:pets", "modify pets in your account")
458+ , ("read:pets", "read your pets") ] } )
475459 , _securitySchemeDescription = Nothing }) ]
476460
477461securityDefinitionsExampleJSON :: Value
478462securityDefinitionsExampleJSON = [aesonQQ|
479463{
480464 "api_key": {
481− "type": "apiKey",
465+ "in": "header",
482466 "name": "api_key",
483− "in": "header"
467+ "type": "apiKey"
484468 },
485469 "petstore_auth": {
486470 "type": "oauth2",
487− "authorizationUrl": "http://swagger.io/api/oauth/dialog",
488− "flow": "implicit",
489− "scopes": {
490− "write:pets": "modify pets in your account",
491− "read:pets": "read your pets"
471+ "flows": {
472+ "implicit": {
473+ "scopes": {
474+ "write:pets": "modify pets in your account",
475+ "read:pets": "read your pets"
476+ },
477+ "authorizationUrl": "http://swagger.io/api/oauth/dialog"
478+ }
492479 }
493480 }
494481}
482+
495483|]
496484
497485oAuth2SecurityDefinitionsReadExample :: SecurityDefinitions
498486oAuth2SecurityDefinitionsReadExample = SecurityDefinitions
499487 [ ("petstore_auth", SecurityScheme
500− { _securitySchemeType = SecuritySchemeOAuth2 (OAuth2Params
501− { _oauth2Flow = OAuth2Implicit "http://swagger.io/api/oauth/dialog"
502− , _oauth2Scopes =
488+ { _securitySchemeType = SecuritySchemeOAuth2 (mempty & implicit ?~ OAuth2Flow
489+ { _oAuth2Params = OAuth2ImplicitFlow "http://swagger.io/api/oauth/dialog"
490+ , _oAath2RefreshUrl = Nothing
491+ , _oAuth2Scopes =
503492 [ ("read:pets", "read your pets") ] } )
504493 , _securitySchemeDescription = Nothing })
505494 ]
@@ -507,10 +496,11 @@ oAuth2SecurityDefinitionsReadExample = SecurityDefinitions
507496oAuth2SecurityDefinitionsWriteExample :: SecurityDefinitions
508497oAuth2SecurityDefinitionsWriteExample = SecurityDefinitions
509498 [ ("petstore_auth", SecurityScheme
510− { _securitySchemeType = SecuritySchemeOAuth2 (OAuth2Params
511− { _oauth2Flow = OAuth2Implicit "http://swagger.io/api/oauth/dialog"
512− , _oauth2Scopes =
513− [ ("write:pets", "modify pets in your account") ] } )
499+ { _securitySchemeType = SecuritySchemeOAuth2 (mempty & implicit ?~ OAuth2Flow
500+ { _oAuth2Params = OAuth2ImplicitFlow "http://swagger.io/api/oauth/dialog"
501+ , _oAath2RefreshUrl = Nothing
502+ , _oAuth2Scopes =
503+ [ ("write:pets", "modify pets in your account") ] } )
514504 , _securitySchemeDescription = Nothing })
515505 ]
516506
@@ -524,11 +514,14 @@ oAuth2SecurityDefinitionsExampleJSON = [aesonQQ|
524514{
525515 "petstore_auth": {
526516 "type": "oauth2",
527− "authorizationUrl": "http://swagger.io/api/oauth/dialog",
528− "flow": "implicit",
529− "scopes": {
530− "write:pets": "modify pets in your account",
531− "read:pets": "read your pets"
517+ "flows": {
518+ "implicit": {
519+ "scopes": {
520+ "write:pets": "modify pets in your account",
521+ "read:pets": "read your pets"
522+ },
523+ "authorizationUrl": "http://swagger.io/api/oauth/dialog"
524+ }
532525 }
533526 }
534527}
@@ -544,57 +537,54 @@ emptyPathsFieldExample = mempty
544537emptyPathsFieldExampleJSON :: Value
545538emptyPathsFieldExampleJSON = [aesonQQ|
546539{
547− "swagger": "2.0",
540+ "openapi": "3.0.0",
548541 "info": {"version": "", "title": ""},
549− "paths": {}
542+ "paths": {},
543+ "components": {}
550544}
551545|]
552546
553547swaggerExample :: Swagger
554548swaggerExample = mempty
555− & basePath ?~ "/"
556− & schemes ?~ [Http]
549+ -- & basePath ?~ "/"
550+ -- & schemes ?~ [Http]
557551 & info .~ (mempty
558552 & version .~ "1.0"
559553 & title .~ "Todo API"
560554 & license ?~ "MIT"
561555 & license._Just.url ?~ URL "http://mit.com"
562− & description ?~ "This is a an API that tests servant-swagger support for a Todo API")
556+ & description ?~ "This is an API that tests servant-swagger support for a Todo API")
563557 & paths.at "/todo/{id}" ?~ (mempty & get ?~ ((mempty :: Operation)
564− & at 200 ?~ Inline (mempty
558+ & responses . at 200 ?~ Inline (mempty
565559 & description .~ "OK"
566− & schema ?~ Inline (mempty
567− & type_ ?~ SwaggerObject
568− & example ?~ [aesonQQ|
569− {
570− "created": 100,
571− "description": "get milk"
572− } |]
573− & description ?~ "This is some real Todo right here"
574− & properties .~
575− [ ("created", Inline $ mempty
576− & type_ ?~ SwaggerInteger
577− & format ?~ "int32")
578− , ("description", Inline (mempty & type_ ?~ SwaggerString))]))
579− & produces ?~ MimeList [ "application/json" ]
560+ & content . at "application/json" ?~ (mempty
561+ & schema ?~ Inline (mempty
562+ & type_ ?~ SwaggerObject
563+ & example ?~ [aesonQQ|
564+ {
565+ "created": 100,
566+ "description": "get milk"
567+ } |]
568+ & description ?~ "This is some real Todo right here"
569+ & properties .~
570+ [ ("created", Inline $ mempty
571+ & type_ ?~ SwaggerInteger
572+ & format ?~ "int32")
573+ , ("description", Inline (mempty & type_ ?~ SwaggerString))])))
580574 & parameters .~
581575 [ Inline $ mempty
582576 & required ?~ True
583577 & name .~ "id"
584578 & description ?~ "TodoId param"
585− & schema .~ ParamOther (mempty
586− & in_ .~ ParamPath
579+ & in_ .~ ParamPath
580+ & schema ?~ Inline (mempty
587581 & type_ ?~ SwaggerString ) ]
588582 & tags .~ InsOrdHS.fromList [ "todo" ] ))
589583
590584swaggerExampleJSON :: Value
591585swaggerExampleJSON = [aesonQQ|
592586{
593− "swagger": "2.0",
594− "basePath": "/",
595− "schemes": [
596− "http"
597− ],
587+ "openapi": "3.0.0",
598588 "info": {
599589 "version": "1.0",
600590 "title": "Todo API",
@@ -602,1085 +592,326 @@ swaggerExampleJSON = [aesonQQ|
602592 "url": "http://mit.com",
603593 "name": "MIT"
604594 },
605− "description": "This is a an API that tests servant-swagger support for a Todo API"
595+ "description": "This is an API that tests servant-swagger support for a Todo API"
606596 },
607597 "paths": {
608598 "/todo/{id}": {
609599 "get": {
610− "responses": {
611− "200": {
612− "schema": {
613− "example": {
614− "created": 100,
615− "description": "get milk"
616− },
617− "type": "object",
618− "description": "This is some real Todo right here",
619− "properties": {
620− "created": {
621− "format": "int32",
622− "type": "integer"
623− },
624− "description": {
625− "type": "string"
626− }
627− }
628− },
629− "description": "OK"
630− }
631− },
632− "produces": [
633− "application/json"
600+ "tags": [
601+ "todo"
634602 ],
635603 "parameters": [
636604 {
637605 "required": true,
606+ "schema": {
607+ "type": "string"
608+ },
638609 "in": "path",
639610 "name": "id",
640− "type": "string",
641611 "description": "TodoId param"
642612 }
643613 ],
644− "tags": [
645− "todo"
646− ]
614+ "responses": {
615+ "200": {
616+ "content": {
617+ "application/json": {
618+ "schema": {
619+ "example": {
620+ "created": 100,
621+ "description": "get milk"
622+ },
623+ "type": "object",
624+ "description": "This is some real Todo right here",
625+ "properties": {
626+ "created": {
627+ "format": "int32",
628+ "type": "integer"
629+ },
630+ "description": {
631+ "type": "string"
632+ }
633+ }
634+ }
635+ }
636+ },
637+ "description": "OK"
638+ }
639+ }
647640 }
648641 }
649− }
642+ },
643+ "components": {}
650644}
651645|]
652646
653647petstoreExampleJSON :: Value
654648petstoreExampleJSON = [aesonQQ|
655649{
656− "swagger":"2.0",
657− "info":{
658− "description":"This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.",
659− "version":"1.0.0",
660− "title":"Swagger Petstore",
661− "termsOfService":"http://swagger.io/terms/",
662− "contact":{
663− "email":"apiteam@swagger.io"
664− },
665− "license":{
666− "name":"Apache 2.0",
667− "url":"http://www.apache.org/licenses/LICENSE-2.0.html"
668− }
669− },
670− "host":"petstore.swagger.io",
671− "basePath":"/v2",
672− "tags":[
673− {
674− "name":"pet",
675− "description":"Everything about your Pets",
676− "externalDocs":{
677− "description":"Find out more",
678− "url":"http://swagger.io"
679− }
680− },
681− {
682− "name":"store",
683− "description":"Access to Petstore orders"
684− },
685− {
686− "name":"user",
687− "description":"Operations about user",
688− "externalDocs":{
689− "description":"Find out more about our store",
690− "url":"http://swagger.io"
691− }
692− }
693− ],
694− "schemes":[
695− "http"
696− ],
697− "paths":{
698− "/pet":{
699− "post":{
700− "tags":[
701− "pet"
702− ],
703− "summary":"Add a new pet to the store",
704− "description":"",
705− "operationId":"addPet",
706− "consumes":[
707− "application/json",
708− "application/xml"
709− ],
710− "produces":[
711− "application/xml",
712− "application/json"
713− ],
714− "parameters":[
715− {
716− "in":"body",
717− "name":"body",
718− "description":"Pet object that needs to be added to the store",
719− "required":true,
720− "schema":{
721− "$ref":"#/definitions/Pet"
722− }
723− }
724− ],
725− "responses":{
726− "405":{
727− "description":"Invalid input"
728− }
729− },
730− "security":[
731− {
732− "petstore_auth":[
733− "write:pets",
734− "read:pets"
735− ]
736− }
737− ]
738− },
739− "put":{
740− "tags":[
741− "pet"
742− ],
743− "summary":"Update an existing pet",
744− "description":"",
745− "operationId":"updatePet",
746− "consumes":[
747− "application/json",
748− "application/xml"
749− ],
750− "produces":[
751− "application/xml",
752− "application/json"
753− ],
754− "parameters":[
755− {
756− "in":"body",
757− "name":"body",
758− "description":"Pet object that needs to be added to the store",
759− "required":true,
760− "schema":{
761− "$ref":"#/definitions/Pet"
762− }
763− }
764− ],
765− "responses":{
766− "400":{
767− "description":"Invalid ID supplied"
768− },
769− "404":{
770− "description":"Pet not found"
771− },
772− "405":{
773− "description":"Validation exception"
774− }
775− },
776− "security":[
777− {
778− "petstore_auth":[
779− "write:pets",
780− "read:pets"
781− ]
782− }
783− ]
784− }
785− },
786− "/pet/findByStatus":{
787− "get":{
788− "tags":[
789− "pet"
790− ],
791− "summary":"Finds Pets by status",
792− "description":"Multiple status values can be provided with comma seperated strings",
793− "operationId":"findPetsByStatus",
794− "produces":[
795− "application/xml",
796− "application/json"
797− ],
798− "parameters":[
799− {
800− "name":"status",
801− "in":"query",
802− "description":"Status values that need to be considered for filter",
803− "required":true,
804− "type":"array",
805− "items":{
806− "type":"string",
807− "enum":[
808− "available",
809− "pending",
810− "sold"
811− ],
812− "default":"available"
813− },
814− "collectionFormat":"csv"
815− }
816− ],
817− "responses":{
818− "200":{
819− "description":"successful operation",
820− "schema":{
821− "type":"array",
822− "items":{
823− "$ref":"#/definitions/Pet"
824− }
825− }
826− },
827− "400":{
828− "description":"Invalid status value"
829− }
830− },
831− "security":[
832− {
833− "petstore_auth":[
834− "write:pets",
835− "read:pets"
836− ]
837− }
838− ]
839− }
840− },
841− "/pet/findByTags":{
842− "get":{
843− "tags":[
844− "pet"
845− ],
846− "summary":"Finds Pets by tags",
847− "description":"Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.",
848− "operationId":"findPetsByTags",
849− "produces":[
850− "application/xml",
851− "application/json"
852− ],
853− "parameters":[
854− {
855− "name":"tags",
856− "in":"query",
857− "description":"Tags to filter by",
858− "required":true,
859− "type":"array",
860− "items":{
861− "type":"string"
862− },
863− "collectionFormat":"csv"
864− }
865− ],
866− "responses":{
867− "200":{
868− "description":"successful operation",
869− "schema":{
870− "type":"array",
871− "items":{
872− "$ref":"#/definitions/Pet"
873− }
874− }
875− },
876− "400":{
877− "description":"Invalid tag value"
878− }
879− },
880− "security":[
881− {
882− "petstore_auth":[
883− "write:pets",
884− "read:pets"
885− ]
886− }
887− ]
888− }
889− },
890− "/pet/{petId}":{
891− "get":{
892− "tags":[
893− "pet"
894− ],
895− "summary":"Find pet by ID",
896− "description":"Returns a single pet",
897− "operationId":"getPetById",
898− "produces":[
899− "application/xml",
900− "application/json"
901− ],
902− "parameters":[
903− {
904− "name":"petId",
905− "in":"path",
906− "description":"ID of pet to return",
907− "required":true,
908− "type":"integer",
909− "format":"int64"
910− }
911− ],
912− "responses":{
913− "200":{
914− "description":"successful operation",
915− "schema":{
916− "$ref":"#/definitions/Pet"
917− }
918− },
919− "400":{
920− "description":"Invalid ID supplied"
921− },
922− "404":{
923− "description":"Pet not found"
924− }
925− },
926− "security":[
927− {
928− "api_key": []
929− }
930− ]
931− },
932− "post":{
933− "tags":[
934− "pet"
935− ],
936− "summary":"Updates a pet in the store with form data",
937− "description":"",
938− "operationId":"updatePetWithForm",
939− "consumes":[
940− "application/x-www-form-urlencoded"
941− ],
942− "produces":[
943− "application/xml",
944− "application/json"
945− ],
946− "parameters":[
947− {
948− "name":"petId",
949− "in":"path",
950− "description":"ID of pet that needs to be updated",
951− "required":true,
952− "type":"integer",
953− "format":"int64"
954− },
955− {
956− "name":"name",
957− "in":"formData",
958− "description":"Updated name of the pet",
959− "required":false,
960− "type":"string"
961− },
962− {
963− "name":"status",
964− "in":"formData",
965− "description":"Updated status of the pet",
966− "required":false,
967− "type":"string"
968− }
969− ],
970− "responses":{
971− "405":{
972− "description":"Invalid input"
973− }
974− },
975− "security":[
976− {
977− "petstore_auth":[
978− "write:pets",
979− "read:pets"
980− ]
981− }
982− ]
983− },
984− "delete":{
985− "tags":[
986− "pet"
987− ],
988− "summary":"Deletes a pet",
989− "description":"",
990− "operationId":"deletePet",
991− "produces":[
992− "application/xml",
993− "application/json"
994− ],
995− "parameters":[
996− {
997− "name":"api_key",
998− "in":"header",
999− "required":false,
1000− "type":"string"
1001− },
1002− {
1003− "name":"petId",
1004− "in":"path",
1005− "description":"Pet id to delete",
1006− "required":true,
1007− "type":"integer",
1008− "format":"int64"
1009− }
1010− ],
1011− "responses":{
1012− "400":{
1013− "description":"Invalid pet value"
1014− }
1015− },
1016− "security":[
1017− {
1018− "petstore_auth":[
1019− "write:pets",
1020− "read:pets"
1021− ]
1022− }
1023− ]
1024− }
1025− },
1026− "/pet/{petId}/uploadImage":{
1027− "post":{
1028− "tags":[
1029− "pet"
1030− ],
1031− "summary":"uploads an image",
1032− "description":"",
1033− "operationId":"uploadFile",
1034− "consumes":[
1035− "multipart/form-data"
1036− ],
1037− "produces":[
1038− "application/json"
1039− ],
1040− "parameters":[
1041− {
1042− "name":"petId",
1043− "in":"path",
1044− "description":"ID of pet to update",
1045− "required":true,
1046− "type":"integer",
1047− "format":"int64"
1048− },
1049− {
1050− "name":"additionalMetadata",
1051− "in":"formData",
1052− "description":"Additional data to pass to server",
1053− "required":false,
1054− "type":"string"
1055− },
1056− {
1057− "name":"file",
1058− "in":"formData",
1059− "description":"file to upload",
1060− "required":false,
1061− "type":"file"
1062− }
1063− ],
1064− "responses":{
1065− "200":{
1066− "description":"successful operation",
1067− "schema":{
1068− "$ref":"#/definitions/ApiResponse"
1069− }
1070− }
1071− },
1072− "security":[
1073− {
1074− "petstore_auth":[
1075− "write:pets",
1076− "read:pets"
1077− ]
1078− }
1079− ]
1080− }
1081− },
1082− "/store/inventory":{
1083− "get":{
1084− "tags":[
1085− "store"
1086− ],
1087− "summary":"Returns pet inventories by status",
1088− "description":"Returns a map of status codes to quantities",
1089− "operationId":"getInventory",
1090− "produces":[
1091− "application/json"
1092− ],
1093− "parameters": [],
1094− "responses":{
1095− "200":{
1096− "description":"successful operation",
1097− "schema":{
1098− "type":"object",
1099− "additionalProperties":{
1100− "type":"integer",
1101− "format":"int32"
1102− }
1103− }
1104− }
1105− },
1106− "security":[
1107− {
1108− "api_key": []
1109− }
1110− ]
1111− }
1112− },
1113− "/store/order":{
1114− "post":{
1115− "tags":[
1116− "store"
1117− ],
1118− "summary":"Place an order for a pet",
1119− "description":"",
1120− "operationId":"placeOrder",
1121− "produces":[
1122− "application/xml",
1123− "application/json"
1124− ],
1125− "parameters":[
1126− {
1127− "in":"body",
1128− "name":"body",
1129− "description":"order placed for purchasing the pet",
1130− "required":true,
1131− "schema":{
1132− "$ref":"#/definitions/Order"
1133− }
1134− }
1135− ],
1136− "responses":{
1137− "200":{
1138− "description":"successful operation",
1139− "schema":{
1140− "$ref":"#/definitions/Order"
1141− }
1142− },
1143− "400":{
1144− "description":"Invalid Order"
1145− }
1146− }
1147− }
1148− },
1149− "/store/order/{orderId}":{
1150− "get":{
1151− "tags":[
1152− "store"
1153− ],
1154− "summary":"Find purchase order by ID",
1155− "description":"For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions",
1156− "operationId":"getOrderById",
1157− "produces":[
1158− "application/xml",
1159− "application/json"
1160− ],
1161− "parameters":[
1162− {
1163− "name":"orderId",
1164− "in":"path",
1165− "description":"ID of pet that needs to be fetched",
1166− "required":true,
1167− "type":"integer",
1168− "maximum":5.0,
1169− "minimum":1.0,
1170− "format":"int64"
1171− }
1172− ],
1173− "responses":{
1174− "200":{
1175− "description":"successful operation",
1176− "schema":{
1177− "$ref":"#/definitions/Order"
1178− }
1179− },
1180− "400":{
1181− "description":"Invalid ID supplied"
1182− },
1183− "404":{
1184− "description":"Order not found"
1185− }
1186− }
1187− },
1188− "delete":{
1189− "tags":[
1190− "store"
1191− ],
1192− "summary":"Delete purchase order by ID",
1193− "description":"For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors",
1194− "operationId":"deleteOrder",
1195− "produces":[
1196− "application/xml",
1197− "application/json"
1198− ],
1199− "parameters":[
1200− {
1201− "name":"orderId",
1202− "in":"path",
1203− "description":"ID of the order that needs to be deleted",
1204− "required":true,
1205− "type":"string",
1206− "minimum":1.0
1207− }
1208− ],
1209− "responses":{
1210− "400":{
1211− "description":"Invalid ID supplied"
1212− },
1213− "404":{
1214− "description":"Order not found"
1215− }
1216− }
1217− }
1218− },
1219− "/user":{
1220− "post":{
1221− "tags":[
1222− "user"
1223− ],
1224− "summary":"Create user",
1225− "description":"This can only be done by the logged in user.",
1226− "operationId":"createUser",
1227− "produces":[
1228− "application/xml",
1229− "application/json"
1230− ],
1231− "parameters":[
1232− {
1233− "in":"body",
1234− "name":"body",
1235− "description":"Created user object",
1236− "required":true,
1237− "schema":{
1238− "$ref":"#/definitions/User"
1239− }
1240− }
1241− ],
1242− "responses":{
1243− "default":{
1244− "description":"successful operation"
1245− }
650+ "openapi": "3.0.0",
651+ "info": {
652+ "version": "1.0.0",
653+ "title": "Swagger Petstore",
654+ "license": {
655+ "name": "MIT"
656+ }
657+ },
658+ "servers": [
659+ {
660+ "url": "http://petstore.swagger.io/v1"
661+ }
662+ ],
663+ "paths": {
664+ "/pets": {
665+ "get": {
666+ "summary": "List all pets",
667+ "operationId": "listPets",
668+ "tags": [
669+ "pets"
670+ ],
671+ "parameters": [
672+ {
673+ "name": "limit",
674+ "in": "query",
675+ "description": "How many items to return at one time (max 100)",
676+ "required": false,
677+ "schema": {
678+ "type": "integer",
679+ "format": "int32"
1246680 }
1247− }
1248− },
1249− "/user/createWithArray":{
1250− "post":{
1251− "tags":[
1252− "user"
1253− ],
1254− "summary":"Creates list of users with given input array",
1255− "description":"",
1256− "operationId":"createUsersWithArrayInput",
1257− "produces":[
1258− "application/xml",
1259− "application/json"
1260− ],
1261− "parameters":[
1262− {
1263− "in":"body",
1264− "name":"body",
1265− "description":"List of user object",
1266− "required":true,
1267− "schema":{
1268− "type":"array",
1269− "items":{
1270− "$ref":"#/definitions/User"
1271− }
681+ }
682+ ],
683+ "responses": {
684+ "200": {
685+ "description": "A paged array of pets",
686+ "headers": {
687+ "x-next": {
688+ "description": "A link to the next page of responses",
689+ "schema": {
690+ "type": "string"
691+ }
692+ }
693+ },
694+ "content": {
695+ "application/json": {
696+ "schema": {
697+ "type": "array",
698+ "items": {
699+ "type": "object",
700+ "required": [
701+ "id",
702+ "name"
703+ ],
704+ "properties": {
705+ "id": {
706+ "type": "integer",
707+ "format": "int64"
708+ },
709+ "name": {
710+ "type": "string"
711+ },
712+ "tag": {
713+ "type": "string"
714+ }
715+ }
1272716 }
1273− }
1274− ],
1275− "responses":{
1276− "default":{
1277− "description":"successful operation"
1278− }
717+ }
718+ }
1279719 }
1280− }
1281− },
1282− "/user/createWithList":{
1283− "post":{
1284− "tags":[
1285− "user"
1286− ],
1287− "summary":"Creates list of users with given input array",
1288− "description":"",
1289− "operationId":"createUsersWithListInput",
1290− "produces":[
1291− "application/xml",
1292− "application/json"
1293− ],
1294− "parameters":[
1295− {
1296− "in":"body",
1297− "name":"body",
1298− "description":"List of user object",
1299− "required":true,
1300− "schema":{
1301− "type":"array",
1302− "items":{
1303− "$ref":"#/definitions/User"
1304− }
720+ },
721+ "default": {
722+ "description": "unexpected error",
723+ "content": {
724+ "application/json": {
725+ "schema": {
726+ "type": "object",
727+ "required": [
728+ "code",
729+ "message"
730+ ],
731+ "properties": {
732+ "code": {
733+ "type": "integer",
734+ "format": "int32"
735+ },
736+ "message": {
737+ "type": "string"
738+ }
1305739 }
1306− }
1307− ],
1308− "responses":{
1309− "default":{
1310− "description":"successful operation"
1311− }
740+ }
741+ }
1312742 }
1313− }
743+ }
744+ }
1314745 },
1315− "/user/login":{
1316− "get":{
1317− "tags":[
1318− "user"
1319− ],
1320− "summary":"Logs user into the system",
1321− "description":"",
1322− "operationId":"loginUser",
1323− "produces":[
1324− "application/xml",
1325− "application/json"
1326− ],
1327− "parameters":[
1328− {
1329− "name":"username",
1330− "in":"query",
1331− "description":"The user name for login",
1332− "required":true,
1333− "type":"string"
1334− },
1335− {
1336− "name":"password",
1337− "in":"query",
1338− "description":"The password for login in clear text",
1339− "required":true,
1340− "type":"string"
1341− }
1342− ],
1343− "responses":{
1344− "200":{
1345− "description":"successful operation",
1346− "schema":{
1347− "type":"string"
1348− },
1349− "headers":{
1350− "X-Rate-Limit":{
1351− "type":"integer",
1352− "format":"int32",
1353− "description":"calls per hour allowed by the user"
1354− },
1355− "X-Expires-After":{
1356− "type":"string",
1357− "format":"date-time",
1358− "description":"date in UTC when toekn expires"
1359− }
746+ "post": {
747+ "summary": "Create a pet",
748+ "operationId": "createPets",
749+ "tags": [
750+ "pets"
751+ ],
752+ "responses": {
753+ "201": {
754+ "description": "Null response"
755+ },
756+ "default": {
757+ "description": "unexpected error",
758+ "content": {
759+ "application/json": {
760+ "schema": {
761+ "type": "object",
762+ "required": [
763+ "code",
764+ "message"
765+ ],
766+ "properties": {
767+ "code": {
768+ "type": "integer",
769+ "format": "int32"
770+ },
771+ "message": {
772+ "type": "string"
773+ }
1360774 }
1361− },
1362− "400":{
1363− "description":"Invalid username/password supplied"
1364− }
775+ }
776+ }
1365777 }
1366− }
1367− },
1368− "/user/logout":{
1369− "get":{
1370− "tags":[
1371− "user"
1372− ],
1373− "summary":"Logs out current logged in user session",
1374− "description":"",
1375− "operationId":"logoutUser",
1376− "produces":[
1377− "application/xml",
1378− "application/json"
1379− ],
1380− "parameters": [],
1381− "responses":{
1382− "default":{
1383− "description":"successful operation"
1384− }
778+ }
779+ }
780+ }
781+ },
782+ "/pets/{petId}": {
783+ "get": {
784+ "summary": "Info for a specific pet",
785+ "operationId": "showPetById",
786+ "tags": [
787+ "pets"
788+ ],
789+ "parameters": [
790+ {
791+ "name": "petId",
792+ "in": "path",
793+ "required": true,
794+ "description": "The id of the pet to retrieve",
795+ "schema": {
796+ "type": "string"
1385797 }
1386− }
1387− },
1388− "/user/{username}":{
1389− "get":{
1390− "tags":[
1391− "user"
1392− ],
1393− "summary":"Get user by user name",
1394− "description":"",
1395− "operationId":"getUserByName",
1396− "produces":[
1397− "application/xml",
1398− "application/json"
1399− ],
1400− "parameters":[
1401− {
1402− "name":"username",
1403− "in":"path",
1404− "description":"The name that needs to be fetched. Use user1 for testing. ",
1405− "required":true,
1406− "type":"string"
1407− }
1408− ],
1409− "responses":{
1410− "200":{
1411− "description":"successful operation",
1412− "schema":{
1413− "$ref":"#/definitions/User"
798+ }
799+ ],
800+ "responses": {
801+ "200": {
802+ "description": "Expected response to a valid request",
803+ "content": {
804+ "application/json": {
805+ "schema": {
806+ "type": "object",
807+ "required": [
808+ "id",
809+ "name"
810+ ],
811+ "properties": {
812+ "id": {
813+ "type": "integer",
814+ "format": "int64"
815+ },
816+ "name": {
817+ "type": "string"
818+ },
819+ "tag": {
820+ "type": "string"
821+ }
1414822 }
1415− },
1416− "400":{
1417− "description":"Invalid username supplied"
1418− },
1419− "404":{
1420− "description":"User not found"
1421− }
823+ }
824+ }
1422825 }
1423− },
1424− "put":{
1425− "tags":[
1426− "user"
1427− ],
1428− "summary":"Updated user",
1429− "description":"This can only be done by the logged in user.",
1430− "operationId":"updateUser",
1431− "produces":[
1432− "application/xml",
1433− "application/json"
1434− ],
1435− "parameters":[
1436− {
1437− "name":"username",
1438− "in":"path",
1439− "description":"name that need to be deleted",
1440− "required":true,
1441− "type":"string"
1442− },
1443− {
1444− "in":"body",
1445− "name":"body",
1446− "description":"Updated user object",
1447− "required":true,
1448− "schema":{
1449− "$ref":"#/definitions/User"
826+ },
827+ "default": {
828+ "description": "unexpected error",
829+ "content": {
830+ "application/json": {
831+ "schema": {
832+ "type": "object",
833+ "required": [
834+ "code",
835+ "message"
836+ ],
837+ "properties": {
838+ "code": {
839+ "type": "integer",
840+ "format": "int32"
841+ },
842+ "message": {
843+ "type": "string"
844+ }
1450845 }
1451− }
1452− ],
1453− "responses":{
1454− "400":{
1455− "description":"Invalid user supplied"
1456− },
1457− "404":{
1458− "description":"User not found"
1459− }
846+ }
847+ }
1460848 }
1461− },
1462− "delete":{
1463− "tags":[
1464− "user"
1465− ],
1466− "summary":"Delete user",
1467− "description":"This can only be done by the logged in user.",
1468− "operationId":"deleteUser",
1469− "produces":[
1470− "application/xml",
1471− "application/json"
1472− ],
1473− "parameters":[
1474− {
1475− "name":"username",
1476− "in":"path",
1477− "description":"The name that needs to be deleted",
1478− "required":true,
1479− "type":"string"
1480− }
1481− ],
1482− "responses":{
1483− "400":{
1484− "description":"Invalid username supplied"
1485− },
1486− "404":{
1487− "description":"User not found"
1488− }
1489− }
1490− }
1491− }
1492− },
1493− "securityDefinitions":{
1494− "petstore_auth":{
1495− "type":"oauth2",
1496− "authorizationUrl":"http://petstore.swagger.io/api/oauth/dialog",
1497− "flow":"implicit",
1498− "scopes":{
1499− "write:pets":"modify pets in your account",
1500− "read:pets":"read your pets"
1501− }
1502− },
1503− "api_key":{
1504− "type":"apiKey",
1505− "name":"api_key",
1506− "in":"header"
849+ }
850+ }
1507851 }
1508− },
1509− "definitions":{
1510− "Order":{
1511− "type":"object",
1512− "properties":{
1513− "id":{
1514− "type":"integer",
1515− "format":"int64"
1516− },
1517− "petId":{
1518− "type":"integer",
1519− "format":"int64"
1520− },
1521− "quantity":{
1522− "type":"integer",
1523− "format":"int32"
1524− },
1525− "shipDate":{
1526− "type":"string",
1527− "format":"date-time"
1528− },
1529− "status":{
1530− "type":"string",
1531− "description":"Order Status",
1532− "enum":[
1533− "placed",
1534− "approved",
1535− "delivered"
1536− ]
1537− },
1538− "complete":{
1539− "type":"boolean",
1540− "default":false
1541− }
1542− },
1543− "xml":{
1544− "name":"Order"
1545− }
1546− },
1547− "Category":{
1548− "type":"object",
1549− "properties":{
1550− "id":{
1551− "type":"integer",
1552− "format":"int64"
1553− },
1554− "name":{
1555− "type":"string"
1556− }
1557− },
1558− "xml":{
1559− "name":"Category"
1560− }
1561− },
1562− "User":{
1563− "type":"object",
1564− "properties":{
1565− "id":{
1566− "type":"integer",
1567− "format":"int64"
1568− },
1569− "username":{
1570− "type":"string"
1571− },
1572− "firstName":{
1573− "type":"string"
1574− },
1575− "lastName":{
1576− "type":"string"
1577− },
1578− "email":{
1579− "type":"string"
1580− },
1581− "password":{
1582− "type":"string"
1583− },
1584− "phone":{
1585− "type":"string"
1586− },
1587− "userStatus":{
1588− "type":"integer",
1589− "format":"int32",
1590− "description":"User Status"
1591− }
1592− },
1593− "xml":{
1594− "name":"User"
1595− }
1596− },
1597− "Tag":{
1598− "type":"object",
1599− "properties":{
1600− "id":{
1601− "type":"integer",
1602− "format":"int64"
1603− },
1604− "name":{
1605− "type":"string"
1606− }
1607− },
1608− "xml":{
1609− "name":"Tag"
1610− }
852+ }
853+ },
854+ "components": {
855+ "schemas": {
856+ "Pet": {
857+ "type": "object",
858+ "required": [
859+ "id",
860+ "name"
861+ ],
862+ "properties": {
863+ "id": {
864+ "type": "integer",
865+ "format": "int64"
866+ },
867+ "name": {
868+ "type": "string"
869+ },
870+ "tag": {
871+ "type": "string"
872+ }
873+ }
1611874 },
1612− "Pet":{
1613− "type":"object",
1614− "required":[
1615− "name",
1616− "photoUrls"
1617− ],
1618− "properties":{
1619− "id":{
1620− "type":"integer",
1621− "format":"int64"
1622− },
1623− "category":{
1624− "$ref":"#/definitions/Category"
1625− },
1626− "name":{
1627− "type":"string",
1628− "example":"doggie"
875+ "Pets": {
876+ "type": "array",
877+ "items": {
878+ "type": "object",
879+ "required": [
880+ "id",
881+ "name"
882+ ],
883+ "properties": {
884+ "id": {
885+ "type": "integer",
886+ "format": "int64"
1629887 },
1630− "photoUrls":{
1631− "type":"array",
1632− "xml":{
1633− "name":"photoUrl",
1634− "wrapped":true
1635− },
1636− "items":{
1637− "type":"string"
1638− }
888+ "name": {
889+ "type": "string"
1639890 },
1640− "tags":{
1641− "type":"array",
1642− "xml":{
1643− "name":"tag",
1644− "wrapped":true
1645− },
1646− "items":{
1647− "$ref":"#/definitions/Tag"
1648− }
1649− },
1650− "status":{
1651− "type":"string",
1652− "description":"pet status in the store",
1653− "enum":[
1654− "available",
1655− "pending",
1656− "sold"
1657− ]
891+ "tag": {
892+ "type": "string"
1658893 }
1659− },
1660− "xml":{
1661− "name":"Pet"
1662− }
894+ }
895+ }
1663896 },
1664− "ApiResponse":{
1665− "type":"object",
1666− "properties":{
1667− "code":{
1668− "type":"integer",
1669− "format":"int32"
1670− },
1671− "type":{
1672− "type":"string"
1673− },
1674− "message":{
1675− "type":"string"
1676− }
1677− }
897+ "Error": {
898+ "type": "object",
899+ "required": [
900+ "code",
901+ "message"
902+ ],
903+ "properties": {
904+ "code": {
905+ "type": "integer",
906+ "format": "int32"
907+ },
908+ "message": {
909+ "type": "string"
910+ }
911+ }
1678912 }
1679− },
1680− "externalDocs":{
1681− "description":"Find out more about Swagger",
1682− "url":"http://swagger.io"
1683− }
913+ }
914+ }
1684915}
1685916|]
1686917
@@ -1702,7 +933,7 @@ compositionSchemaExampleJSON = [aesonQQ|
1702933 "type": "object",
1703934 "allOf": [
1704935 {
1705− "$ref": "#/definitions/Other"
936+ "$ref": "#/components/schemas/Other"
1706937 },
1707938 {
1708939 "type": "object",