@@ -6,6 +6,20 @@
66-- and Swagger-Codegen to generate clients in various languages.
77-- Additional utilities can also take advantage of the resulting files, such as testing tools.
88module Data.Swagger (
9+ -- * How to use this library
10+ -- $howto
11+
12+ -- ** @'Monoid'@ instances
13+ -- $monoids
14+
15+ -- ** Lenses and prisms
16+ -- $lens
17+
18+ -- ** Schema specification
19+ -- $schema
20+
21+ -- * Re-exports
22+ module Data.Swagger.Lens,
923 module Data.Swagger.ParamSchema,
1024 module Data.Swagger.Schema,
1125
@@ -14,25 +28,25 @@ module Data.Swagger (
1428 Host(..),
1529 Scheme(..),
1630
17− -- * Info types
31+ -- ** Info types
1832 Info(..),
1933 Contact(..),
2034 License(..),
2135
22− -- * Paths
36+ -- ** Paths
2337 Paths(..),
2438 PathItem(..),
2539
26− -- * Operations
40+ -- ** Operations
2741 Tag(..),
2842 Operation(..),
2943
30− -- * Types and formats
44+ -- ** Types and formats
3145 SwaggerType(..),
3246 Format,
3347 CollectionFormat(..),
3448
35− -- * Parameters
49+ -- ** Parameters
3650 Param(..),
3751 ParamAnySchema(..),
3852 ParamOtherSchema(..),
@@ -42,45 +56,159 @@ module Data.Swagger (
4256 Header(..),
4357 Example(..),
4458
45− -- * Schemas
59+ -- ** Schemas
4660 ParamSchema(..),
4761 Schema(..),
4862 SwaggerItems(..),
4963 Xml(..),
5064
51− -- * Responses
65+ -- ** Responses
5266 Responses(..),
5367 Response(..),
5468
55− -- * Security
69+ -- ** Security
5670 SecurityScheme(..),
5771 SecuritySchemeType(..),
5872 SecurityRequirement(..),
5973
60− -- ** API key
74+ -- *** API key
6175 ApiKeyParams(..),
6276 ApiKeyLocation(..),
6377
64− -- ** OAuth2
78+ -- *** OAuth2
6579 OAuth2Params(..),
6680 OAuth2Flow(..),
6781 AuthorizationURL,
6882 TokenURL,
6983
70− -- * External documentation
84+ -- ** External documentation
7185 ExternalDocs(..),
7286
73− -- * References
87+ -- ** References
7488 Reference(..),
7589 Referenced(..),
7690
77− -- * Miscellaneous
91+ -- ** Miscellaneous
7892 MimeList(..),
7993 URL(..),
8094) where
8195
96+import Data.Swagger.Lens
8297import Data.Swagger.ParamSchema
8398import Data.Swagger.Schema
8499
85100import Data.Swagger.Internal
86101
102+-- $setup
103+-- >>> import Control.Lens
104+-- >>> import Data.Aeson
105+-- >>> import Data.Monoid
106+-- >>> import Data.Proxy
107+-- >>> import GHC.Generics
108+-- >>> :set -XDeriveGeneric
109+-- >>> :set -XOverloadedStrings
110+-- >>> :set -XOverloadedLists
111+-- >>> :set -fno-warn-missing-methods
112+
113+-- $howto
114+--
115+-- This section explains how to use this library to work with Swagger specification.
116+
117+-- $monoids
118+--
119+-- Virtually all types representing Swagger specification have @'Monoid'@ instances.
120+-- The @'Monoid'@ type class provides two methods — @'mempty'@ and @'mappend'@.
121+--
122+-- In this library you can use @'mempty'@ for a default/empty value. For instance:
123+--
124+-- >>> encode (mempty :: Swagger)
125+-- "{\"swagger\":\"2.0\",\"info\":{\"version\":\"\",\"title\":\"\"}}"
126+--
127+-- As you can see some spec properties (e.g. @"version"@) are there even when the spec is empty.
128+-- That is because these properties are actually required ones.
129+--
130+-- You /should/ always override the default (empty) value for these properties,
131+-- although it is not strictly necessary:
132+--
133+-- >>> encode mempty { _infoTitle = "Todo API", _infoVersion = "1.0" }
134+-- "{\"version\":\"1.0\",\"title\":\"Todo API\"}"
135+--
136+-- You can merge two values using @'mappend'@ or its infix version @('<>')@:
137+--
138+-- >>> encode $ mempty { _infoTitle = "Todo API" } <> mempty { _infoVersion = "1.0" }
139+-- "{\"version\":\"1.0\",\"title\":\"Todo API\"}"
140+--
141+-- This can be useful for combining specifications of endpoints into a whole API specification:
142+--
143+-- @
144+-- \-\- /account subAPI specification
145+-- accountAPI :: Swagger
146+--
147+-- \-\- /task subAPI specification
148+-- taskAPI :: Swagger
149+--
150+-- \-\- while API specification is just a combination
151+-- \-\- of subAPIs' specifications
152+-- api :: Swagger
153+-- api = accountAPI <> taskAPI
154+-- @
155+
156+-- $lens
157+--
158+-- Since @'Swagger'@ has a fairly complex structure, lenses and prisms are used
159+-- to modify this structure. In combination with @'Monoid'@ instances, lenses
160+-- also make it fairly simple to construct/modify any part of the specification:
161+--
162+-- >>> :{
163+-- encode $ mempty & pathsMap .~
164+-- [ ("/user", mempty & pathItemGet ?~ (mempty
165+-- & operationProduces ?~ MimeList ["application/json"]
166+-- & operationResponses .~ (mempty
167+-- & responsesResponses . at 200 ?~ Inline (mempty & responseSchema ?~ Ref (Reference "#/definitions/User")))))]
168+-- :}
169+-- "{\"/user\":{\"get\":{\"responses\":{\"200\":{\"schema\":{\"$ref\":\"#/definitions/#/definitions/User\"},\"description\":\"\"}},\"produces\":[\"application/json\"]}}}"
170+--
171+-- Since @'ParamSchema'@ is basically the /base schema specification/, a special
172+-- @'HasParamSchema'@ class has been introduced to generalize @'ParamSchema'@ lenses
173+-- and allow them to be used by any type that has a @'ParamSchema'@:
174+--
175+-- >>> :{
176+-- encode $ mempty
177+-- & schemaTitle ?~ "Email"
178+-- & schemaType .~ SwaggerString
179+-- & schemaFormat ?~ "email"
180+-- :}
181+-- "{\"format\":\"email\",\"title\":\"Email\",\"type\":\"string\"}"
182+
183+-- $schema
184+--
185+-- This library provides two classes for schema encoding.
186+-- Both these classes provide means to encode _types_ as Swagger _schemas_.
187+--
188+-- @'ToParamSchema'@ is intended to be used for primitive API endpoint parameters,
189+-- such as query parameters, headers and URL path pieces.
190+-- Its corresponding value-encoding class is @'ToHttpApiData'@ (from @http-api-data@ package).
191+--
192+-- @'ToSchema'@ is used for request and response bodies and mostly differ from
193+-- primitive parameters by allowing objects/mappings in addition to primitive types and arrays.
194+-- Its corresponding value-encoding class is @'ToJSON'@ (from @aeson@ package).
195+--
196+-- While lenses and prisms make it easy to define schemas, it might be that you don't need to:
197+-- @'ToSchema'@ and @'ToParamSchema'@ classes both have default @'Generic'@-based implementations!
198+--
199+-- @'ToSchema'@ default implementation is also aligned with @'ToJSON'@ default implementation with
200+-- the only difference being for sum encoding. @'ToJSON'@ defaults sum encoding to @'defaultTaggedObject'@,
201+-- while @'ToSchema'@ defaults to something which corresponds to @'ObjectWithSingleField'@. This is due to
202+-- @'defaultTaggedObject'@ behavior being hard to specify in Swagger.
203+--
204+-- Here's an example showing @'ToJSON'@–@'ToSchema'@ correspondance:
205+--
206+-- >>> data Person = Person { name :: String, age :: Integer } deriving Generic
207+-- >>> instance ToJSON Person
208+-- >>> instance ToSchema Person
209+-- >>> encode (Person "David" 28)
210+-- "{\"age\":28,\"name\":\"David\"}"
211+-- >>> encode $ toSchema (Proxy :: Proxy Person)
212+-- "{\"required\":[\"name\",\"age\"],\"type\":\"object\",\"properties\":{\"age\":{\"type\":\"integer\"},\"name\":{\"type\":\"string\"}}}"
213+--
214+