git.iko.soy/typeable/openapi3
on master help sign in
Merge pull request #6 from GetShopTV/petstore-test
e972646Nickolay Kudasov
.travis.yml+1
@@ -25,6 +25,7 @@ matrix:
25 packages:
25 packages:
26 - ghc-head
26 - ghc-head
27 allow_failures:
27 allow_failures:
28+ - env: GHCVER=7.8.4 STACK_YAML=stack-7.8.yaml
28 - env: GHCVER=head STACK_YAML=stack-head.yaml
29 - env: GHCVER=head STACK_YAML=stack-head.yaml
29
30
30cache:
31cache:
src/Data/Swagger/Internal.hs+27−19
@@ -277,7 +277,7 @@ data SwaggerParameter = SwaggerParameter
277 } deriving (Eq, Show, Generic)
277 } deriving (Eq, Show, Generic)
278
278
279data SwaggerParameterSchema
279data SwaggerParameterSchema
280− = SwaggerParameterBody SwaggerSchema
280+ = SwaggerParameterBody (SwaggerReferenced SwaggerSchema)
281 | SwaggerParameterOther SwaggerParameterOtherSchema
281 | SwaggerParameterOther SwaggerParameterOtherSchema
282 deriving (Eq, Show)
282 deriving (Eq, Show)
283
283
@@ -408,8 +408,8 @@ data SwaggerSchema = SwaggerSchema
408 } deriving (Eq, Show, Generic)
408 } deriving (Eq, Show, Generic)
409
409
410data SwaggerSchemaItems
410data SwaggerSchemaItems
411− = SwaggerSchemaItemsObject SwaggerSchema
411+ = SwaggerSchemaItemsObject (SwaggerReferenced SwaggerSchema)
412− | SwaggerSchemaItemsArray [SwaggerSchema]
412+ | SwaggerSchemaItemsArray [SwaggerReferenced SwaggerSchema]
413 deriving (Eq, Show)
413 deriving (Eq, Show)
414
414
415data SwaggerSchemaCommon = SwaggerSchemaCommon
415data SwaggerSchemaCommon = SwaggerSchemaCommon
@@ -460,22 +460,22 @@ data SwaggerXml = SwaggerXml
460 -- Default value is @False@.
460 -- Default value is @False@.
461 -- The definition takes effect only when defined alongside type being array (outside the items).
461 -- The definition takes effect only when defined alongside type being array (outside the items).
462 , swaggerXmlWrapped :: Bool
462 , swaggerXmlWrapped :: Bool
463− } deriving (Eq, Show)
463+ } deriving (Eq, Show, Generic)
464
464
465data SwaggerItems = SwaggerItems
465data SwaggerItems = SwaggerItems
466 { -- | The internal type of the array.
466 { -- | The internal type of the array.
467 swaggerItemsType :: SwaggerItemsType
467 swaggerItemsType :: SwaggerItemsType
468
468
469 -- | The extending format for the previously mentioned type.
469 -- | The extending format for the previously mentioned type.
470− , swaggerItemsFormat :: SwaggerFormat
470+ , swaggerItemsFormat :: Maybe SwaggerFormat
471
471
472 -- | __Required if type is @'SwaggerItemsArray'@.__
472 -- | __Required if type is @'SwaggerItemsArray'@.__
473 -- Describes the type of items in the array.
473 -- Describes the type of items in the array.
474− , swaggerItemsItems :: SwaggerItems
474+ , swaggerItemsItems :: Maybe SwaggerItems
475
475
476 -- | Determines the format of the array if type array is used.
476 -- | Determines the format of the array if type array is used.
477 -- Default value is @'SwaggerItemsCollectionCSV'@.
477 -- Default value is @'SwaggerItemsCollectionCSV'@.
478− , swaggerItemsCollectionFormat :: SwaggerItemsCollectionFormat
478+ , swaggerItemsCollectionFormat :: Maybe SwaggerItemsCollectionFormat
479
479
480 , swaggerItemsCommon :: SwaggerSchemaCommon
480 , swaggerItemsCommon :: SwaggerSchemaCommon
481 } deriving (Eq, Show, Generic)
481 } deriving (Eq, Show, Generic)
@@ -508,7 +508,7 @@ data SwaggerResponse = SwaggerResponse
508 -- If this field does not exist, it means no content is returned as part of the response.
508 -- If this field does not exist, it means no content is returned as part of the response.
509 -- As an extension to the Schema Object, its root type value may also be "file".
509 -- As an extension to the Schema Object, its root type value may also be "file".
510 -- This SHOULD be accompanied by a relevant produces mime-type.
510 -- This SHOULD be accompanied by a relevant produces mime-type.
511− , swaggerResponseSchema :: Maybe SwaggerSchema
511+ , swaggerResponseSchema :: Maybe (SwaggerReferenced SwaggerSchema)
512
512
513 -- | A list of headers that are sent with the response.
513 -- | A list of headers that are sent with the response.
514 , swaggerResponseHeaders :: HashMap HeaderName SwaggerHeader
514 , swaggerResponseHeaders :: HashMap HeaderName SwaggerHeader
@@ -531,11 +531,11 @@ data SwaggerHeader = SwaggerHeader
531
531
532 -- | __Required if type is @'SwaggerItemsArray'@__.
532 -- | __Required if type is @'SwaggerItemsArray'@__.
533 -- Describes the type of items in the array.
533 -- Describes the type of items in the array.
534− , swaggerHeaderItems :: SwaggerItems
534+ , swaggerHeaderItems :: Maybe SwaggerItems
535
535
536 -- | Determines the format of the array if type array is used.
536 -- | Determines the format of the array if type array is used.
537 -- Default value is @'SwaggerItemsCollectionCSV'@.
537 -- Default value is @'SwaggerItemsCollectionCSV'@.
538− , swaggerHeaderCollectionFormat :: SwaggerItemsCollectionFormat
538+ , swaggerHeaderCollectionFormat :: Maybe SwaggerItemsCollectionFormat
539
539
540 , swaggerHeaderCommon :: SwaggerSchemaCommon
540 , swaggerHeaderCommon :: SwaggerSchemaCommon
541 } deriving (Eq, Show, Generic)
541 } deriving (Eq, Show, Generic)
@@ -724,10 +724,12 @@ instance SwaggerMonoid (HashMap Text SwaggerSchema) where
724
724
725instance SwaggerMonoid (HashMap Text (SwaggerReferenced SwaggerSchema)) where
725instance SwaggerMonoid (HashMap Text (SwaggerReferenced SwaggerSchema)) where
726 swaggerMempty = HashMap.empty
726 swaggerMempty = HashMap.empty
727− swaggerMappend = HashMap.unionWith merge
727+ swaggerMappend = HashMap.unionWith swaggerMappend
728− where
728+
729+instance Monoid a => SwaggerMonoid (SwaggerReferenced a) where
730+ swaggerMempty = SwaggerInline mempty
729− merge (SwaggerInline x) (SwaggerInline y) = SwaggerInline (x <> y)
731+ swaggerMappend (SwaggerInline x) (SwaggerInline y) = SwaggerInline (x <> y)
730− merge _ y = y
732+ swaggerMappend _ y = y
731
733
732instance SwaggerMonoid (HashMap Text SwaggerParameter) where
734instance SwaggerMonoid (HashMap Text SwaggerParameter) where
733 swaggerMempty = HashMap.empty
735 swaggerMempty = HashMap.empty
@@ -778,11 +780,11 @@ deriveJSON (jsonPrefix "swaggerSchema") ''SwaggerSchemaCommon
778deriveJSONDefault ''SwaggerScheme
780deriveJSONDefault ''SwaggerScheme
779deriveJSON' ''SwaggerTag
781deriveJSON' ''SwaggerTag
780deriveJSON' ''SwaggerExternalDocs
782deriveJSON' ''SwaggerExternalDocs
781−deriveJSON' ''SwaggerXml
782
783
783deriveToJSON' ''SwaggerOperation
784deriveToJSON' ''SwaggerOperation
784deriveToJSON' ''SwaggerResponse
785deriveToJSON' ''SwaggerResponse
785deriveToJSON' ''SwaggerPathItem
786deriveToJSON' ''SwaggerPathItem
787+deriveToJSON' ''SwaggerXml
786
788
787-- =======================================================================
789-- =======================================================================
788-- Manual ToJSON instances
790-- Manual ToJSON instances
@@ -850,7 +852,7 @@ instance ToJSON SwaggerParameter where
850 toJSON = genericToJSONWithSub "schema" (jsonPrefix "swaggerParameter")
852 toJSON = genericToJSONWithSub "schema" (jsonPrefix "swaggerParameter")
851
853
852instance ToJSON SwaggerParameterSchema where
854instance ToJSON SwaggerParameterSchema where
853− toJSON (SwaggerParameterBody s) = toJSON s <+> object [ "in" .= ("body" :: Text) ]
855+ toJSON (SwaggerParameterBody s) = object [ "in" .= ("body" :: Text), "schema" .= s ]
854 toJSON (SwaggerParameterOther s) = toJSON s
856 toJSON (SwaggerParameterOther s) = toJSON s
855
857
856instance ToJSON SwaggerParameterOtherSchema where
858instance ToJSON SwaggerParameterOtherSchema where
@@ -936,10 +938,10 @@ instance FromJSON SwaggerItems where
936instance FromJSON SwaggerHost where
938instance FromJSON SwaggerHost where
937 parseJSON (String s) =
939 parseJSON (String s) =
938 case fromInteger <$> readMaybe portStr of
940 case fromInteger <$> readMaybe portStr of
939− Nothing | not (null portStr) -> empty
941+ Nothing | not (null portStr) -> fail $ "Invalid port `" ++ portStr ++ "'"
940 mport -> pure $ SwaggerHost host mport
942 mport -> pure $ SwaggerHost host mport
941 where
943 where
942− (hostText, portText) = Text.breakOnEnd ":" s
944+ (hostText, portText) = Text.breakOn ":" s
943 [host, portStr] = map Text.unpack [hostText, portText]
945 [host, portStr] = map Text.unpack [hostText, portText]
944 parseJSON _ = empty
946 parseJSON _ = empty
945
947
@@ -957,7 +959,9 @@ instance FromJSON SwaggerParameterSchema where
957 parseJSON json@(Object o) = do
959 parseJSON json@(Object o) = do
958 (i :: Text) <- o .: "in"
960 (i :: Text) <- o .: "in"
959 case i of
961 case i of
962+ "body" -> do
963+ schema <- o .: "schema"
960− "body" -> SwaggerParameterBody <$> parseJSON json
964+ SwaggerParameterBody <$> parseJSON schema
961 _ -> SwaggerParameterOther <$> parseJSON json
965 _ -> SwaggerParameterOther <$> parseJSON json
962 parseJSON _ = empty
966 parseJSON _ = empty
963
967
@@ -1003,3 +1007,7 @@ instance FromJSON a => FromJSON (SwaggerReferenced a) where
1003 = SwaggerRef <$> parseJSON json
1007 = SwaggerRef <$> parseJSON json
1004 <|> SwaggerInline <$> parseJSON json
1008 <|> SwaggerInline <$> parseJSON json
1005
1009
1010+instance FromJSON SwaggerXml where
1011+ parseJSON = genericParseJSON (jsonPrefix "swaggerXml")
1012+ `withDefaults` [ "attribute" .= False, "wrapped" .= False ]
1013+
test/Data/SwaggerSpec.hs+1045−2
@@ -1,5 +1,6 @@
1{-# LANGUAGE OverloadedLists #-}
1{-# LANGUAGE OverloadedLists #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE ScopedTypeVariables #-}
3{-# LANGUAGE QuasiQuotes #-}
4{-# LANGUAGE QuasiQuotes #-}
4module Data.SwaggerSpec where
5module Data.SwaggerSpec where
5
6
@@ -54,7 +55,11 @@ spec = do
54 describe "Parameters Definition Object" $ parametersDefinitionExample <~> parametersDefinitionExampleJSON
55 describe "Parameters Definition Object" $ parametersDefinitionExample <~> parametersDefinitionExampleJSON
55 describe "Responses Definition Object" $ responsesDefinitionExample <~> responsesDefinitionExampleJSON
56 describe "Responses Definition Object" $ responsesDefinitionExample <~> responsesDefinitionExampleJSON
56 describe "Security Definitions Object" $ securityDefinitionsExample <~> securityDefinitionsExampleJSON
57 describe "Security Definitions Object" $ securityDefinitionsExample <~> securityDefinitionsExampleJSON
58+ describe "Swagger Object" $ do
57− describe "Swagger Object" $ swaggerExample <~> swaggerExampleJSON
59+ context "Todo Example" $ swaggerExample <~> swaggerExampleJSON
60+ context "PetStore Example" $
61+ it "decodes successfully" $ do
62+ fromJSON petstoreExampleJSON `shouldSatisfy` (\x -> case x of Success (_ :: Swagger) -> True; _ -> False)
58
63
59main :: IO ()
64main :: IO ()
60main = hspec spec
65main = hspec spec
@@ -526,7 +531,7 @@ swaggerExample = mempty
526 { swaggerOperationResponses = mempty
531 { swaggerOperationResponses = mempty
527 { swaggerResponsesResponses =
532 { swaggerResponsesResponses =
528 [ (200, SwaggerInline mempty
533 [ (200, SwaggerInline mempty
529− { swaggerResponseSchema = Just mempty
534+ { swaggerResponseSchema = Just $ SwaggerInline mempty
530 { swaggerSchemaExample = Just [aesonQQ|
535 { swaggerSchemaExample = Just [aesonQQ|
531 {
536 {
532 "created": 100,
537 "created": 100,
@@ -614,3 +619,1041 @@ swaggerExampleJSON = [aesonQQ|
614 }
619 }
615}
620}
616|]
621|]
622+
623+petstoreExampleJSON :: Value
624+petstoreExampleJSON = [aesonQQ|
625+{
626+ "swagger":"2.0",
627+ "info":{
628+ "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.",
629+ "version":"1.0.0",
630+ "title":"Swagger Petstore",
631+ "termsOfService":"http://swagger.io/terms/",
632+ "contact":{
633+ "email":"apiteam@swagger.io"
634+ },
635+ "license":{
636+ "name":"Apache 2.0",
637+ "url":"http://www.apache.org/licenses/LICENSE-2.0.html"
638+ }
639+ },
640+ "host":"petstore.swagger.io",
641+ "basePath":"/v2",
642+ "tags":[
643+ {
644+ "name":"pet",
645+ "description":"Everything about your Pets",
646+ "externalDocs":{
647+ "description":"Find out more",
648+ "url":"http://swagger.io"
649+ }
650+ },
651+ {
652+ "name":"store",
653+ "description":"Access to Petstore orders"
654+ },
655+ {
656+ "name":"user",
657+ "description":"Operations about user",
658+ "externalDocs":{
659+ "description":"Find out more about our store",
660+ "url":"http://swagger.io"
661+ }
662+ }
663+ ],
664+ "schemes":[
665+ "http"
666+ ],
667+ "paths":{
668+ "/pet":{
669+ "post":{
670+ "tags":[
671+ "pet"
672+ ],
673+ "summary":"Add a new pet to the store",
674+ "description":"",
675+ "operationId":"addPet",
676+ "consumes":[
677+ "application/json",
678+ "application/xml"
679+ ],
680+ "produces":[
681+ "application/xml",
682+ "application/json"
683+ ],
684+ "parameters":[
685+ {
686+ "in":"body",
687+ "name":"body",
688+ "description":"Pet object that needs to be added to the store",
689+ "required":true,
690+ "schema":{
691+ "$ref":"#/definitions/Pet"
692+ }
693+ }
694+ ],
695+ "responses":{
696+ "405":{
697+ "description":"Invalid input"
698+ }
699+ },
700+ "security":[
701+ {
702+ "petstore_auth":[
703+ "write:pets",
704+ "read:pets"
705+ ]
706+ }
707+ ]
708+ },
709+ "put":{
710+ "tags":[
711+ "pet"
712+ ],
713+ "summary":"Update an existing pet",
714+ "description":"",
715+ "operationId":"updatePet",
716+ "consumes":[
717+ "application/json",
718+ "application/xml"
719+ ],
720+ "produces":[
721+ "application/xml",
722+ "application/json"
723+ ],
724+ "parameters":[
725+ {
726+ "in":"body",
727+ "name":"body",
728+ "description":"Pet object that needs to be added to the store",
729+ "required":true,
730+ "schema":{
731+ "$ref":"#/definitions/Pet"
732+ }
733+ }
734+ ],
735+ "responses":{
736+ "400":{
737+ "description":"Invalid ID supplied"
738+ },
739+ "404":{
740+ "description":"Pet not found"
741+ },
742+ "405":{
743+ "description":"Validation exception"
744+ }
745+ },
746+ "security":[
747+ {
748+ "petstore_auth":[
749+ "write:pets",
750+ "read:pets"
751+ ]
752+ }
753+ ]
754+ }
755+ },
756+ "/pet/findByStatus":{
757+ "get":{
758+ "tags":[
759+ "pet"
760+ ],
761+ "summary":"Finds Pets by status",
762+ "description":"Multiple status values can be provided with comma seperated strings",
763+ "operationId":"findPetsByStatus",
764+ "produces":[
765+ "application/xml",
766+ "application/json"
767+ ],
768+ "parameters":[
769+ {
770+ "name":"status",
771+ "in":"query",
772+ "description":"Status values that need to be considered for filter",
773+ "required":true,
774+ "type":"array",
775+ "items":{
776+ "type":"string",
777+ "enum":[
778+ "available",
779+ "pending",
780+ "sold"
781+ ],
782+ "default":"available"
783+ },
784+ "collectionFormat":"csv"
785+ }
786+ ],
787+ "responses":{
788+ "200":{
789+ "description":"successful operation",
790+ "schema":{
791+ "type":"array",
792+ "items":{
793+ "$ref":"#/definitions/Pet"
794+ }
795+ }
796+ },
797+ "400":{
798+ "description":"Invalid status value"
799+ }
800+ },
801+ "security":[
802+ {
803+ "petstore_auth":[
804+ "write:pets",
805+ "read:pets"
806+ ]
807+ }
808+ ]
809+ }
810+ },
811+ "/pet/findByTags":{
812+ "get":{
813+ "tags":[
814+ "pet"
815+ ],
816+ "summary":"Finds Pets by tags",
817+ "description":"Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.",
818+ "operationId":"findPetsByTags",
819+ "produces":[
820+ "application/xml",
821+ "application/json"
822+ ],
823+ "parameters":[
824+ {
825+ "name":"tags",
826+ "in":"query",
827+ "description":"Tags to filter by",
828+ "required":true,
829+ "type":"array",
830+ "items":{
831+ "type":"string"
832+ },
833+ "collectionFormat":"csv"
834+ }
835+ ],
836+ "responses":{
837+ "200":{
838+ "description":"successful operation",
839+ "schema":{
840+ "type":"array",
841+ "items":{
842+ "$ref":"#/definitions/Pet"
843+ }
844+ }
845+ },
846+ "400":{
847+ "description":"Invalid tag value"
848+ }
849+ },
850+ "security":[
851+ {
852+ "petstore_auth":[
853+ "write:pets",
854+ "read:pets"
855+ ]
856+ }
857+ ]
858+ }
859+ },
860+ "/pet/{petId}":{
861+ "get":{
862+ "tags":[
863+ "pet"
864+ ],
865+ "summary":"Find pet by ID",
866+ "description":"Returns a single pet",
867+ "operationId":"getPetById",
868+ "produces":[
869+ "application/xml",
870+ "application/json"
871+ ],
872+ "parameters":[
873+ {
874+ "name":"petId",
875+ "in":"path",
876+ "description":"ID of pet to return",
877+ "required":true,
878+ "type":"integer",
879+ "format":"int64"
880+ }
881+ ],
882+ "responses":{
883+ "200":{
884+ "description":"successful operation",
885+ "schema":{
886+ "$ref":"#/definitions/Pet"
887+ }
888+ },
889+ "400":{
890+ "description":"Invalid ID supplied"
891+ },
892+ "404":{
893+ "description":"Pet not found"
894+ }
895+ },
896+ "security":[
897+ {
898+ "api_key":[
899+ ]
900+ }
901+ ]
902+ },
903+ "post":{
904+ "tags":[
905+ "pet"
906+ ],
907+ "summary":"Updates a pet in the store with form data",
908+ "description":"",
909+ "operationId":"updatePetWithForm",
910+ "consumes":[
911+ "application/x-www-form-urlencoded"
912+ ],
913+ "produces":[
914+ "application/xml",
915+ "application/json"
916+ ],
917+ "parameters":[
918+ {
919+ "name":"petId",
920+ "in":"path",
921+ "description":"ID of pet that needs to be updated",
922+ "required":true,
923+ "type":"integer",
924+ "format":"int64"
925+ },
926+ {
927+ "name":"name",
928+ "in":"formData",
929+ "description":"Updated name of the pet",
930+ "required":false,
931+ "type":"string"
932+ },
933+ {
934+ "name":"status",
935+ "in":"formData",
936+ "description":"Updated status of the pet",
937+ "required":false,
938+ "type":"string"
939+ }
940+ ],
941+ "responses":{
942+ "405":{
943+ "description":"Invalid input"
944+ }
945+ },
946+ "security":[
947+ {
948+ "petstore_auth":[
949+ "write:pets",
950+ "read:pets"
951+ ]
952+ }
953+ ]
954+ },
955+ "delete":{
956+ "tags":[
957+ "pet"
958+ ],
959+ "summary":"Deletes a pet",
960+ "description":"",
961+ "operationId":"deletePet",
962+ "produces":[
963+ "application/xml",
964+ "application/json"
965+ ],
966+ "parameters":[
967+ {
968+ "name":"api_key",
969+ "in":"header",
970+ "required":false,
971+ "type":"string"
972+ },
973+ {
974+ "name":"petId",
975+ "in":"path",
976+ "description":"Pet id to delete",
977+ "required":true,
978+ "type":"integer",
979+ "format":"int64"
980+ }
981+ ],
982+ "responses":{
983+ "400":{
984+ "description":"Invalid pet value"
985+ }
986+ },
987+ "security":[
988+ {
989+ "petstore_auth":[
990+ "write:pets",
991+ "read:pets"
992+ ]
993+ }
994+ ]
995+ }
996+ },
997+ "/pet/{petId}/uploadImage":{
998+ "post":{
999+ "tags":[
1000+ "pet"
1001+ ],
1002+ "summary":"uploads an image",
1003+ "description":"",
1004+ "operationId":"uploadFile",
1005+ "consumes":[
1006+ "multipart/form-data"
1007+ ],
1008+ "produces":[
1009+ "application/json"
1010+ ],
1011+ "parameters":[
1012+ {
1013+ "name":"petId",
1014+ "in":"path",
1015+ "description":"ID of pet to update",
1016+ "required":true,
1017+ "type":"integer",
1018+ "format":"int64"
1019+ },
1020+ {
1021+ "name":"additionalMetadata",
1022+ "in":"formData",
1023+ "description":"Additional data to pass to server",
1024+ "required":false,
1025+ "type":"string"
1026+ },
1027+ {
1028+ "name":"file",
1029+ "in":"formData",
1030+ "description":"file to upload",
1031+ "required":false,
1032+ "type":"file"
1033+ }
1034+ ],
1035+ "responses":{
1036+ "200":{
1037+ "description":"successful operation",
1038+ "schema":{
1039+ "$ref":"#/definitions/ApiResponse"
1040+ }
1041+ }
1042+ },
1043+ "security":[
1044+ {
1045+ "petstore_auth":[
1046+ "write:pets",
1047+ "read:pets"
1048+ ]
1049+ }
1050+ ]
1051+ }
1052+ },
1053+ "/store/inventory":{
1054+ "get":{
1055+ "tags":[
1056+ "store"
1057+ ],
1058+ "summary":"Returns pet inventories by status",
1059+ "description":"Returns a map of status codes to quantities",
1060+ "operationId":"getInventory",
1061+ "produces":[
1062+ "application/json"
1063+ ],
1064+ "parameters":[
1065+ ],
1066+ "responses":{
1067+ "200":{
1068+ "description":"successful operation",
1069+ "schema":{
1070+ "type":"object",
1071+ "additionalProperties":{
1072+ "type":"integer",
1073+ "format":"int32"
1074+ }
1075+ }
1076+ }
1077+ },
1078+ "security":[
1079+ {
1080+ "api_key":[
1081+ ]
1082+ }
1083+ ]
1084+ }
1085+ },
1086+ "/store/order":{
1087+ "post":{
1088+ "tags":[
1089+ "store"
1090+ ],
1091+ "summary":"Place an order for a pet",
1092+ "description":"",
1093+ "operationId":"placeOrder",
1094+ "produces":[
1095+ "application/xml",
1096+ "application/json"
1097+ ],
1098+ "parameters":[
1099+ {
1100+ "in":"body",
1101+ "name":"body",
1102+ "description":"order placed for purchasing the pet",
1103+ "required":true,
1104+ "schema":{
1105+ "$ref":"#/definitions/Order"
1106+ }
1107+ }
1108+ ],
1109+ "responses":{
1110+ "200":{
1111+ "description":"successful operation",
1112+ "schema":{
1113+ "$ref":"#/definitions/Order"
1114+ }
1115+ },
1116+ "400":{
1117+ "description":"Invalid Order"
1118+ }
1119+ }
1120+ }
1121+ },
1122+ "/store/order/{orderId}":{
1123+ "get":{
1124+ "tags":[
1125+ "store"
1126+ ],
1127+ "summary":"Find purchase order by ID",
1128+ "description":"For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions",
1129+ "operationId":"getOrderById",
1130+ "produces":[
1131+ "application/xml",
1132+ "application/json"
1133+ ],
1134+ "parameters":[
1135+ {
1136+ "name":"orderId",
1137+ "in":"path",
1138+ "description":"ID of pet that needs to be fetched",
1139+ "required":true,
1140+ "type":"integer",
1141+ "maximum":5.0,
1142+ "minimum":1.0,
1143+ "format":"int64"
1144+ }
1145+ ],
1146+ "responses":{
1147+ "200":{
1148+ "description":"successful operation",
1149+ "schema":{
1150+ "$ref":"#/definitions/Order"
1151+ }
1152+ },
1153+ "400":{
1154+ "description":"Invalid ID supplied"
1155+ },
1156+ "404":{
1157+ "description":"Order not found"
1158+ }
1159+ }
1160+ },
1161+ "delete":{
1162+ "tags":[
1163+ "store"
1164+ ],
1165+ "summary":"Delete purchase order by ID",
1166+ "description":"For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors",
1167+ "operationId":"deleteOrder",
1168+ "produces":[
1169+ "application/xml",
1170+ "application/json"
1171+ ],
1172+ "parameters":[
1173+ {
1174+ "name":"orderId",
1175+ "in":"path",
1176+ "description":"ID of the order that needs to be deleted",
1177+ "required":true,
1178+ "type":"string",
1179+ "minimum":1.0
1180+ }
1181+ ],
1182+ "responses":{
1183+ "400":{
1184+ "description":"Invalid ID supplied"
1185+ },
1186+ "404":{
1187+ "description":"Order not found"
1188+ }
1189+ }
1190+ }
1191+ },
1192+ "/user":{
1193+ "post":{
1194+ "tags":[
1195+ "user"
1196+ ],
1197+ "summary":"Create user",
1198+ "description":"This can only be done by the logged in user.",
1199+ "operationId":"createUser",
1200+ "produces":[
1201+ "application/xml",
1202+ "application/json"
1203+ ],
1204+ "parameters":[
1205+ {
1206+ "in":"body",
1207+ "name":"body",
1208+ "description":"Created user object",
1209+ "required":true,
1210+ "schema":{
1211+ "$ref":"#/definitions/User"
1212+ }
1213+ }
1214+ ],
1215+ "responses":{
1216+ "default":{
1217+ "description":"successful operation"
1218+ }
1219+ }
1220+ }
1221+ },
1222+ "/user/createWithArray":{
1223+ "post":{
1224+ "tags":[
1225+ "user"
1226+ ],
1227+ "summary":"Creates list of users with given input array",
1228+ "description":"",
1229+ "operationId":"createUsersWithArrayInput",
1230+ "produces":[
1231+ "application/xml",
1232+ "application/json"
1233+ ],
1234+ "parameters":[
1235+ {
1236+ "in":"body",
1237+ "name":"body",
1238+ "description":"List of user object",
1239+ "required":true,
1240+ "schema":{
1241+ "type":"array",
1242+ "items":{
1243+ "$ref":"#/definitions/User"
1244+ }
1245+ }
1246+ }
1247+ ],
1248+ "responses":{
1249+ "default":{
1250+ "description":"successful operation"
1251+ }
1252+ }
1253+ }
1254+ },
1255+ "/user/createWithList":{
1256+ "post":{
1257+ "tags":[
1258+ "user"
1259+ ],
1260+ "summary":"Creates list of users with given input array",
1261+ "description":"",
1262+ "operationId":"createUsersWithListInput",
1263+ "produces":[
1264+ "application/xml",
1265+ "application/json"
1266+ ],
1267+ "parameters":[
1268+ {
1269+ "in":"body",
1270+ "name":"body",
1271+ "description":"List of user object",
1272+ "required":true,
1273+ "schema":{
1274+ "type":"array",
1275+ "items":{
1276+ "$ref":"#/definitions/User"
1277+ }
1278+ }
1279+ }
1280+ ],
1281+ "responses":{
1282+ "default":{
1283+ "description":"successful operation"
1284+ }
1285+ }
1286+ }
1287+ },
1288+ "/user/login":{
1289+ "get":{
1290+ "tags":[
1291+ "user"
1292+ ],
1293+ "summary":"Logs user into the system",
1294+ "description":"",
1295+ "operationId":"loginUser",
1296+ "produces":[
1297+ "application/xml",
1298+ "application/json"
1299+ ],
1300+ "parameters":[
1301+ {
1302+ "name":"username",
1303+ "in":"query",
1304+ "description":"The user name for login",
1305+ "required":true,
1306+ "type":"string"
1307+ },
1308+ {
1309+ "name":"password",
1310+ "in":"query",
1311+ "description":"The password for login in clear text",
1312+ "required":true,
1313+ "type":"string"
1314+ }
1315+ ],
1316+ "responses":{
1317+ "200":{
1318+ "description":"successful operation",
1319+ "schema":{
1320+ "type":"string"
1321+ },
1322+ "headers":{
1323+ "X-Rate-Limit":{
1324+ "type":"integer",
1325+ "format":"int32",
1326+ "description":"calls per hour allowed by the user"
1327+ },
1328+ "X-Expires-After":{
1329+ "type":"string",
1330+ "format":"date-time",
1331+ "description":"date in UTC when toekn expires"
1332+ }
1333+ }
1334+ },
1335+ "400":{
1336+ "description":"Invalid username/password supplied"
1337+ }
1338+ }
1339+ }
1340+ },
1341+ "/user/logout":{
1342+ "get":{
1343+ "tags":[
1344+ "user"
1345+ ],
1346+ "summary":"Logs out current logged in user session",
1347+ "description":"",
1348+ "operationId":"logoutUser",
1349+ "produces":[
1350+ "application/xml",
1351+ "application/json"
1352+ ],
1353+ "parameters":[
1354+ ],
1355+ "responses":{
1356+ "default":{
1357+ "description":"successful operation"
1358+ }
1359+ }
1360+ }
1361+ },
1362+ "/user/{username}":{
1363+ "get":{
1364+ "tags":[
1365+ "user"
1366+ ],
1367+ "summary":"Get user by user name",
1368+ "description":"",
1369+ "operationId":"getUserByName",
1370+ "produces":[
1371+ "application/xml",
1372+ "application/json"
1373+ ],
1374+ "parameters":[
1375+ {
1376+ "name":"username",
1377+ "in":"path",
1378+ "description":"The name that needs to be fetched. Use user1 for testing. ",
1379+ "required":true,
1380+ "type":"string"
1381+ }
1382+ ],
1383+ "responses":{
1384+ "200":{
1385+ "description":"successful operation",
1386+ "schema":{
1387+ "$ref":"#/definitions/User"
1388+ }
1389+ },
1390+ "400":{
1391+ "description":"Invalid username supplied"
1392+ },
1393+ "404":{
1394+ "description":"User not found"
1395+ }
1396+ }
1397+ },
1398+ "put":{
1399+ "tags":[
1400+ "user"
1401+ ],
1402+ "summary":"Updated user",
1403+ "description":"This can only be done by the logged in user.",
1404+ "operationId":"updateUser",
1405+ "produces":[
1406+ "application/xml",
1407+ "application/json"
1408+ ],
1409+ "parameters":[
1410+ {
1411+ "name":"username",
1412+ "in":"path",
1413+ "description":"name that need to be deleted",
1414+ "required":true,
1415+ "type":"string"
1416+ },
1417+ {
1418+ "in":"body",
1419+ "name":"body",
1420+ "description":"Updated user object",
1421+ "required":true,
1422+ "schema":{
1423+ "$ref":"#/definitions/User"
1424+ }
1425+ }
1426+ ],
1427+ "responses":{
1428+ "400":{
1429+ "description":"Invalid user supplied"
1430+ },
1431+ "404":{
1432+ "description":"User not found"
1433+ }
1434+ }
1435+ },
1436+ "delete":{
1437+ "tags":[
1438+ "user"
1439+ ],
1440+ "summary":"Delete user",
1441+ "description":"This can only be done by the logged in user.",
1442+ "operationId":"deleteUser",
1443+ "produces":[
1444+ "application/xml",
1445+ "application/json"
1446+ ],
1447+ "parameters":[
1448+ {
1449+ "name":"username",
1450+ "in":"path",
1451+ "description":"The name that needs to be deleted",
1452+ "required":true,
1453+ "type":"string"
1454+ }
1455+ ],
1456+ "responses":{
1457+ "400":{
1458+ "description":"Invalid username supplied"
1459+ },
1460+ "404":{
1461+ "description":"User not found"
1462+ }
1463+ }
1464+ }
1465+ }
1466+ },
1467+ "securityDefinitions":{
1468+ "petstore_auth":{
1469+ "type":"oauth2",
1470+ "authorizationUrl":"http://petstore.swagger.io/api/oauth/dialog",
1471+ "flow":"implicit",
1472+ "scopes":{
1473+ "write:pets":"modify pets in your account",
1474+ "read:pets":"read your pets"
1475+ }
1476+ },
1477+ "api_key":{
1478+ "type":"apiKey",
1479+ "name":"api_key",
1480+ "in":"header"
1481+ }
1482+ },
1483+ "definitions":{
1484+ "Order":{
1485+ "type":"object",
1486+ "properties":{
1487+ "id":{
1488+ "type":"integer",
1489+ "format":"int64"
1490+ },
1491+ "petId":{
1492+ "type":"integer",
1493+ "format":"int64"
1494+ },
1495+ "quantity":{
1496+ "type":"integer",
1497+ "format":"int32"
1498+ },
1499+ "shipDate":{
1500+ "type":"string",
1501+ "format":"date-time"
1502+ },
1503+ "status":{
1504+ "type":"string",
1505+ "description":"Order Status",
1506+ "enum":[
1507+ "placed",
1508+ "approved",
1509+ "delivered"
1510+ ]
1511+ },
1512+ "complete":{
1513+ "type":"boolean",
1514+ "default":false
1515+ }
1516+ },
1517+ "xml":{
1518+ "name":"Order"
1519+ }
1520+ },
1521+ "Category":{
1522+ "type":"object",
1523+ "properties":{
1524+ "id":{
1525+ "type":"integer",
1526+ "format":"int64"
1527+ },
1528+ "name":{
1529+ "type":"string"
1530+ }
1531+ },
1532+ "xml":{
1533+ "name":"Category"
1534+ }
1535+ },
1536+ "User":{
1537+ "type":"object",
1538+ "properties":{
1539+ "id":{
1540+ "type":"integer",
1541+ "format":"int64"
1542+ },
1543+ "username":{
1544+ "type":"string"
1545+ },
1546+ "firstName":{
1547+ "type":"string"
1548+ },
1549+ "lastName":{
1550+ "type":"string"
1551+ },
1552+ "email":{
1553+ "type":"string"
1554+ },
1555+ "password":{
1556+ "type":"string"
1557+ },
1558+ "phone":{
1559+ "type":"string"
1560+ },
1561+ "userStatus":{
1562+ "type":"integer",
1563+ "format":"int32",
1564+ "description":"User Status"
1565+ }
1566+ },
1567+ "xml":{
1568+ "name":"User"
1569+ }
1570+ },
1571+ "Tag":{
1572+ "type":"object",
1573+ "properties":{
1574+ "id":{
1575+ "type":"integer",
1576+ "format":"int64"
1577+ },
1578+ "name":{
1579+ "type":"string"
1580+ }
1581+ },
1582+ "xml":{
1583+ "name":"Tag"
1584+ }
1585+ },
1586+ "Pet":{
1587+ "type":"object",
1588+ "required":[
1589+ "name",
1590+ "photoUrls"
1591+ ],
1592+ "properties":{
1593+ "id":{
1594+ "type":"integer",
1595+ "format":"int64"
1596+ },
1597+ "category":{
1598+ "$ref":"#/definitions/Category"
1599+ },
1600+ "name":{
1601+ "type":"string",
1602+ "example":"doggie"
1603+ },
1604+ "photoUrls":{
1605+ "type":"array",
1606+ "xml":{
1607+ "name":"photoUrl",
1608+ "wrapped":true
1609+ },
1610+ "items":{
1611+ "type":"string"
1612+ }
1613+ },
1614+ "tags":{
1615+ "type":"array",
1616+ "xml":{
1617+ "name":"tag",
1618+ "wrapped":true
1619+ },
1620+ "items":{
1621+ "$ref":"#/definitions/Tag"
1622+ }
1623+ },
1624+ "status":{
1625+ "type":"string",
1626+ "description":"pet status in the store",
1627+ "enum":[
1628+ "available",
1629+ "pending",
1630+ "sold"
1631+ ]
1632+ }
1633+ },
1634+ "xml":{
1635+ "name":"Pet"
1636+ }
1637+ },
1638+ "ApiResponse":{
1639+ "type":"object",
1640+ "properties":{
1641+ "code":{
1642+ "type":"integer",
1643+ "format":"int32"
1644+ },
1645+ "type":{
1646+ "type":"string"
1647+ },
1648+ "message":{
1649+ "type":"string"
1650+ }
1651+ }
1652+ }
1653+ },
1654+ "externalDocs":{
1655+ "description":"Find out more about Swagger",
1656+ "url":"http://swagger.io"
1657+ }
1658+}
1659+|]