git.iko.soy/typeable/swagger2
on 91de35c help sign in
288 lines 10 kB history raw
1-- |
2-- Module: Data.Swagger
3-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
4-- Stability: experimental
5--
6-- Swagger™ is a project used to describe and document RESTful APIs.
7--
8-- The Swagger specification defines a set of files required to describe such an API.
9-- These files can then be used by the Swagger-UI project to display the API
10-- and Swagger-Codegen to generate clients in various languages.
11-- Additional utilities can also take advantage of the resulting files, such as testing tools.
12module Data.Swagger (
13 -- * How to use this library
14 -- $howto
16 -- ** @'Monoid'@ instances
17 -- $monoids
19 -- ** Lenses and prisms
20 -- $lens
22 -- ** Schema specification
23 -- $schema
25 -- ** Manipulation
26 -- $manipulation
28 -- ** Validation
29 -- $validation
31 -- * Re-exports
32 module Data.Swagger.Lens,
33 module Data.Swagger.Operation,
34 module Data.Swagger.ParamSchema,
35 module Data.Swagger.Schema,
36 module Data.Swagger.Schema.Validation,
38 -- * Swagger specification
39 Swagger(..),
40 Host(..),
41 Scheme(..),
43 -- ** Info types
44 Info(..),
45 Contact(..),
46 License(..),
48 -- ** PathItem
49 PathItem(..),
51 -- ** Operations
52 Operation(..),
53 Tag(..),
54 TagName,
56 -- ** Types and formats
57 SwaggerType(..),
58 Format,
59 Definitions,
60 CollectionFormat(..),
62 -- ** Parameters
63 Param(..),
64 ParamAnySchema(..),
65 ParamOtherSchema(..),
66 ParamLocation(..),
67 ParamName,
68 Header(..),
69 HeaderName,
70 Example(..),
72 -- ** Schemas
73 ParamSchema(..),
74 Schema(..),
75 NamedSchema(..),
76 SwaggerItems(..),
77 Xml(..),
78 Pattern,
80 -- ** Responses
81 Responses(..),
82 Response(..),
83 HttpStatusCode,
85 -- ** Security
86 SecurityScheme(..),
87 SecuritySchemeType(..),
88 SecurityRequirement(..),
90 -- *** API key
91 ApiKeyParams(..),
92 ApiKeyLocation(..),
94 -- *** OAuth2
95 OAuth2Params(..),
96 OAuth2Flow(..),
97 AuthorizationURL,
98 TokenURL,
100 -- ** External documentation
101 ExternalDocs(..),
103 -- ** References
104 Reference(..),
105 Referenced(..),
107 -- ** Miscellaneous
108 MimeList(..),
109 URL(..),
110) where
112import Data.Swagger.Lens
113import Data.Swagger.Operation
114import Data.Swagger.ParamSchema
115import Data.Swagger.Schema
116import Data.Swagger.Schema.Validation
118import Data.Swagger.Internal
120-- $setup
121-- >>> import Control.Lens
122-- >>> import Data.Aeson
123-- >>> import Data.Monoid
124-- >>> import Data.Proxy
125-- >>> import GHC.Generics
126-- >>> :set -XDeriveGeneric
127-- >>> :set -XOverloadedStrings
128-- >>> :set -XOverloadedLists
129-- >>> :set -fno-warn-missing-methods
131-- $howto
132--
133-- This section explains how to use this library to work with Swagger specification.
135-- $monoids
136--
137-- Virtually all types representing Swagger specification have @'Monoid'@ instances.
138-- The @'Monoid'@ type class provides two methods — @'mempty'@ and @'mappend'@.
139--
140-- In this library you can use @'mempty'@ for a default/empty value. For instance:
141--
142-- >>> encode (mempty :: Swagger)
143-- "{\"swagger\":\"2.0\",\"info\":{\"version\":\"\",\"title\":\"\"}}"
144--
145-- As you can see some spec properties (e.g. @"version"@) are there even when the spec is empty.
146-- That is because these properties are actually required ones.
147--
148-- You /should/ always override the default (empty) value for these properties,
149-- although it is not strictly necessary:
150--
151-- >>> encode mempty { _infoTitle = "Todo API", _infoVersion = "1.0" }
152-- "{\"version\":\"1.0\",\"title\":\"Todo API\"}"
153--
154-- You can merge two values using @'mappend'@ or its infix version @('<>')@:
155--
156-- >>> encode $ mempty { _infoTitle = "Todo API" } <> mempty { _infoVersion = "1.0" }
157-- "{\"version\":\"1.0\",\"title\":\"Todo API\"}"
158--
159-- This can be useful for combining specifications of endpoints into a whole API specification:
160--
161-- @
162-- \-\- /account subAPI specification
163-- accountAPI :: Swagger
164--
165-- \-\- /task subAPI specification
166-- taskAPI :: Swagger
167--
168-- \-\- while API specification is just a combination
169-- \-\- of subAPIs' specifications
170-- api :: Swagger
171-- api = accountAPI <> taskAPI
172-- @
174-- $lens
175--
176-- Since @'Swagger'@ has a fairly complex structure, lenses and prisms are used
177-- to work comfortably with it. In combination with @'Monoid'@ instances, lenses
178-- make it fairly simple to construct/modify any part of the specification:
179--
180-- >>> :{
181-- encode $ (mempty :: Swagger)
182-- & definitions .~ [ ("User", mempty & type_ .~ SwaggerString) ]
183-- & paths .~
184-- [ ("/user", mempty & get ?~ (mempty
185-- & produces ?~ MimeList ["application/json"]
186-- & at 200 ?~ ("OK" & _Inline.schema ?~ Ref (Reference "User"))
187-- & at 404 ?~ "User info not found")) ]
188-- :}
189-- "{\"swagger\":\"2.0\",\"info\":{\"version\":\"\",\"title\":\"\"},\"paths\":{\"/user\":{\"get\":{\"produces\":[\"application/json\"],\"responses\":{\"404\":{\"description\":\"User info not found\"},\"200\":{\"schema\":{\"$ref\":\"#/definitions/User\"},\"description\":\"OK\"}}}}},\"definitions\":{\"User\":{\"type\":\"string\"}}}"
190--
191-- In the snippet above we declare an API with a single path @/user@. This path provides method @GET@
192-- which produces @application/json@ output. It should respond with code @200@ and body specified
193-- by schema @User@ which is defined in @'definitions'@ property of swagger specification.
194-- Alternatively it may respond with code @404@ meaning that user info is not found.
195--
196-- For convenience, @swagger2@ uses /classy field lenses/. It means that
197-- field accessor names can be overloaded for different types. One such
198-- common field is @'description'@. Many components of a Swagger specification
199-- can have descriptions, and you can use the same name for them:
200--
201-- >>> encode $ (mempty :: Response) & description .~ "No content"
202-- "{\"description\":\"No content\"}"
203-- >>> :{
204-- encode $ (mempty :: Schema)
205-- & type_ .~ SwaggerBoolean
206-- & description ?~ "To be or not to be"
207-- :}
208-- "{\"description\":\"To be or not to be\",\"type\":\"boolean\"}"
209--
210-- @'ParamSchema'@ is basically the /base schema specification/ and many types contain it (see @'HasParamSchema'@).
211-- So for convenience, all @'ParamSchema'@ fields are transitively made fields of the type that has it.
212-- For example, you can use @'type_'@ to access @'SwaggerType'@ of @'Header'@ schema without having to use @'paramSchema'@:
213--
214-- >>> encode $ (mempty :: Header) & type_ .~ SwaggerNumber
215-- "{\"type\":\"number\"}"
216--
217-- Additionally, to simplify working with @'Response'@, both @'Operation'@ and @'Responses'@
218-- have direct access to it via @'at' code@. Example:
219--
220-- >>> :{
221-- encode $ (mempty :: Operation)
222-- & at 404 ?~ "Not found"
223-- :}
224-- "{\"responses\":{\"404\":{\"description\":\"Not found\"}}}"
225--
226-- You might've noticed that @'type_'@ has an extra underscore in its name
227-- compared to, say, @'description'@ field accessor.
228-- This is because @type@ is a keyword in Haskell.
229-- A few other field accessors are modified in this way:
230--
231-- - @'in_'@, @'type_'@, @'default_'@ (as keywords);
232-- - @'maximum_'@, @'minimum_'@, @'head_'@ (as conflicting with @Prelude@);
233-- - @'enum_'@ (as conflicting with @Control.Lens@).
235-- $schema
236--
237-- @'ParamSchema'@ and @'Schema'@ are the two core types for data model specification.
238--
239-- @'ParamSchema' t@ specifies all the common properties, available for every data schema.
240-- The @t@ parameter imposes some restrictions on @type@ and @items@ properties (see @'SwaggerType'@ and @'SwaggerItems'@).
241--
242-- @'Schema'@ is used for request and response bodies and allows specifying objects
243-- with properties in addition to what @'ParamSchema'@ provides.
244--
245-- In most cases you will have a Haskell data type for which you would like to
246-- define a corresponding schema. To facilitate this use case
247-- @swagger2@ provides two classes for schema encoding.
248-- Both these classes provide means to encode /types/ as Swagger /schemas/.
249--
250-- @'ToParamSchema'@ is intended to be used for primitive API endpoint parameters,
251-- such as query parameters, headers and URL path pieces.
252-- Its corresponding value-encoding class is @'ToHttpApiData'@ (from @http-api-data@ package).
253--
254-- @'ToSchema'@ is used for request and response bodies and mostly differ from
255-- primitive parameters by allowing objects/mappings in addition to primitive types and arrays.
256-- Its corresponding value-encoding class is @'ToJSON'@ (from @aeson@ package).
257--
258-- While lenses and prisms make it easy to define schemas, it might be that you don't need to:
259-- @'ToSchema'@ and @'ToParamSchema'@ classes both have default @'Generic'@-based implementations!
260--
261-- @'ToSchema'@ default implementation is also aligned with @'ToJSON'@ default implementation with
262-- the only difference being for sum encoding. @'ToJSON'@ defaults sum encoding to @'defaultTaggedObject'@,
263-- while @'ToSchema'@ defaults to something which corresponds to @'ObjectWithSingleField'@. This is due to
264-- @'defaultTaggedObject'@ behavior being hard to specify in Swagger.
265--
266-- Here's an example showing @'ToJSON'@–@'ToSchema'@ correspondance:
267--
268-- >>> data Person = Person { name :: String, age :: Integer } deriving Generic
269-- >>> instance ToJSON Person
270-- >>> instance ToSchema Person
271-- >>> encode (Person "David" 28)
272-- "{\"age\":28,\"name\":\"David\"}"
273-- >>> encode $ toSchema (Proxy :: Proxy Person)
274-- "{\"required\":[\"name\",\"age\"],\"properties\":{\"name\":{\"type\":\"string\"},\"age\":{\"type\":\"integer\"}},\"type\":\"object\"}"
276-- $manipulation
277-- Sometimes you have to work with an imported or generated @'Swagger'@.
278-- For instance, <servant-swagger http://hackage.haskell.org/package/servant-swagger> generates basic @'Swagger'@
279-- for a type-level servant API.
280--
281-- Lenses and prisms can be used to manipulate such specification to add additional information, tags, extra responses, etc.
282-- To facilitate common needs, @"Data.Swagger.Operation"@ module provides useful helpers.
284-- $validation
285-- While @'ToParamSchema'@ and @'ToSchema'@ provide means to easily obtain schemas for Haskell types,
286-- there is no static mechanism to ensure those instances correspond to the @'ToHttpApiData'@ or @'ToJSON'@ instances.
287--
288-- @"Data.Swagger.Schema.Validation"@ addresses @'ToJSON'@/@'ToSchema'@ validation.