Skip to content

Commit c7bd7ae

Browse files
kosmikussvobot
authored andcommitted
Generalise over the Swagger datatype.
This change modifies the previously introduced generalisation of the Haskell datatype that holds the Swagger specification to an aeson Value. By using an aeson Value, all ordering information of object fields is being lost. This information is in principle preserved by aeson, when going via Encoding rather than Value. With this patch, we do not perform any aeson-related translation in the servant-swagger-ui code, and simply use the original datatype. It is servant's own responsibility to handle the actual conversion of the datatype to JSON. Based on haskell-servant#89
1 parent d4533c5 commit c7bd7ae

File tree

12 files changed

+74
-32
lines changed

12 files changed

+74
-32
lines changed

servant-swagger-ui-core/Changelog.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
# 0.3.6
2+
3+
- Generalize to support arbitrary type instead of hardcoded `Value`.
4+
5+
`SwaggerSchemaUI` now needs one more parameter which typically is
6+
either `Swagger` or `OpenApi`.
7+
8+
To migrate from older version, alter your API type from
9+
`SwaggerSchemaUI "swagger-ui" "swagger.json"`
10+
to
11+
`SwaggerSchemaUI "swagger-ui" "swagger.json" Swagger`
12+
13+
Or in case of the more generic variant, old
14+
`SwaggerSchemaUI' "foo-ui" ("foo" :> "swagger.json" :> Get '[JSON] Value)`
15+
becomes
16+
`SwaggerSchemaUI' "foo-ui" ("foo" :> "swagger.json" :> Get '[JSON] Swagger)`
17+
118
# 0.3.5
219

320
- Generalize `SwaggerSchemaUI` and `swaggerSchemaUIServerImpl` to support arbitrary `Value` instead

servant-swagger-ui-core/servant-swagger-ui-core.cabal

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 1.12
22
name: servant-swagger-ui-core
3-
version: 0.3.5
3+
version: 0.3.6
44
synopsis: Servant swagger ui core components
55
category: Web, Servant, Swagger
66
description:
@@ -36,7 +36,6 @@ library
3636
ghc-options: -Wall
3737
build-depends:
3838
base >=4.7 && <4.17
39-
, aeson >=0.8.0.2 && <2.1.0
4039
, blaze-markup >=0.7.0.2 && <0.9
4140
, bytestring >=0.10.4.0 && <0.12
4241
, http-media >=0.7.1.3 && <0.9

servant-swagger-ui-core/src/Servant/Swagger/UI/Core.hs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
-- :\<|> "cat" :> Capture ":name" CatName :> Get '[JSON] Cat
2424
--
2525
-- -- | API type with bells and whistles, i.e. schema file and swagger-ui.
26-
-- type API = 'SwaggerSchemaUI' "swagger-ui" "swagger.json"
26+
-- type API = 'SwaggerSchemaUI' "swagger-ui" "swagger.json" Swagger
2727
-- :\<|> BasicAPI
2828
--
2929
-- -- | Servant server for an API
@@ -46,7 +46,6 @@ module Servant.Swagger.UI.Core (
4646
Handler,
4747
) where
4848

49-
import Data.Aeson (ToJSON (..), Value)
5049
import Data.ByteString (ByteString)
5150
import GHC.TypeLits (KnownSymbol, Symbol, symbolVal)
5251
import Network.Wai.Application.Static (embeddedSettings, staticApp)
@@ -58,7 +57,7 @@ import qualified Data.Text as T
5857

5958
-- | Swagger schema + ui api.
6059
--
61-
-- @SwaggerSchemaUI "swagger-ui" "swagger.json"@ will result into following hierarchy:
60+
-- @SwaggerSchemaUI "swagger-ui" "swagger.json" Swagger@ will result into following hierarchy:
6261
--
6362
-- @
6463
-- \/swagger.json
@@ -67,10 +66,11 @@ import qualified Data.Text as T
6766
-- \/swagger-ui\/...
6867
-- @
6968
--
70-
-- This type does not actually force served type to be @Swagger@ from @swagger2@ package,
71-
-- it could be arbitrary @aeson@ 'Value'.
72-
type SwaggerSchemaUI (dir :: Symbol) (schema :: Symbol) =
73-
SwaggerSchemaUI' dir (schema :> Get '[JSON] Value)
69+
-- The third type parameter specifies which Haskell datatype contains the Swagger
70+
-- description. Typical instantiations are @Swagger@ from the @swagger2@ package,
71+
-- and @OpenApi@ from the @openapi3@ package.
72+
type SwaggerSchemaUI (dir :: Symbol) (schema :: Symbol) (a :: *) =
73+
SwaggerSchemaUI' dir (schema :> Get '[JSON] a)
7474

7575
-- | Use 'SwaggerSchemaUI'' when you need even more control over
7676
-- where @swagger.json@ is served (e.g. subdirectory).
@@ -103,11 +103,11 @@ instance (KnownSymbol dir, HasLink api, Link ~ MkLink api Link, IsElem api api)
103103
proxyApi = Proxy :: Proxy api
104104

105105
swaggerSchemaUIServerImpl
106-
:: (Monad m, ServerT api m ~ m Value, ToJSON a)
106+
:: (Monad m, ServerT api m ~ m a)
107107
=> T.Text -> [(FilePath, ByteString)]
108108
-> a -> ServerT (SwaggerSchemaUI' dir api) m
109109
swaggerSchemaUIServerImpl indexTemplate files swagger
110-
= swaggerSchemaUIServerImpl' indexTemplate files $ return $ toJSON swagger
110+
= swaggerSchemaUIServerImpl' indexTemplate files $ return $ swagger
111111

112112
-- | Use a custom server to serve the Swagger spec source.
113113
swaggerSchemaUIServerImpl'

servant-swagger-ui-example/src/Main.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import Prelude ()
1616
import Prelude.Compat
1717

1818
import Control.Lens hiding ((.=))
19-
import Data.Aeson (FromJSON, ToJSON, Value)
19+
import Data.Aeson (FromJSON, ToJSON)
2020
import Data.Maybe (fromMaybe)
2121
import Data.String (IsString (..))
2222
import Data.Text (Text)
@@ -136,13 +136,13 @@ type BasicAPI = Get '[PlainText, JSON] Text
136136

137137
type API =
138138
-- this serves both: swagger.json and swagger-ui
139-
SwaggerSchemaUI "swagger-ui" "swagger.json"
139+
SwaggerSchemaUI "swagger-ui" "swagger.json" Swagger
140140
:<|> BasicAPI
141141

142142
-- To test nested case
143143
type API' = API
144144
:<|> "nested" :> API
145-
:<|> SwaggerSchemaUI' "foo-ui" ("foo" :> "swagger.json" :> Get '[JSON] Value)
145+
:<|> SwaggerSchemaUI' "foo-ui" ("foo" :> "swagger.json" :> Get '[JSON] Swagger)
146146

147147
-- Implementation
148148

@@ -174,7 +174,7 @@ server' uiFlavour = server Normal
174174
-- Unfortunately we have to specify the basePath manually atm.
175175

176176
schemaUiServer
177-
:: (Server api ~ Handler Value)
177+
:: (Server api ~ Handler Swagger)
178178
=> Swagger -> Server (SwaggerSchemaUI' dir api)
179179
schemaUiServer = case uiFlavour of
180180
Original -> swaggerSchemaUIServer

servant-swagger-ui-jensoleg/servant-swagger-ui-jensoleg.cabal

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 1.12
22
name: servant-swagger-ui-jensoleg
3-
version: 0.3.4
3+
version: 0.3.6
44
synopsis: Servant swagger ui: Jens-Ole Graulund theme
55
category: Web, Servant, Swagger
66
description:
@@ -82,10 +82,9 @@ source-repository head
8282
library
8383
hs-source-dirs: src
8484
ghc-options: -Wall
85-
build-depends: servant-swagger-ui-core >=0.3.5 && <0.4
85+
build-depends: servant-swagger-ui-core >=0.3.6 && <0.4
8686
build-depends:
8787
base >=4.7 && <4.17
88-
, aeson >=0.8.0.2 && <2.1.0
8988
, bytestring >=0.10.4.0 && <0.12
9089
, file-embed-lzma >=0 && <0.1
9190
, servant >=0.14 && <0.20

servant-swagger-ui-jensoleg/src/Servant/Swagger/UI/JensOleG.hs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ module Servant.Swagger.UI.JensOleG (
5555

5656
import Servant.Swagger.UI.Core
5757

58-
import Data.Aeson (ToJSON, Value)
5958
import Data.ByteString (ByteString)
6059
import Data.Text (Text)
6160
import FileEmbedLzma
@@ -67,7 +66,7 @@ import Servant
6766
--
6867
-- See <https://github.com/jensoleg/swagger-ui>
6968
jensolegSwaggerSchemaUIServer
70-
:: (Server api ~ Handler Value, ToJSON a)
69+
:: (Server api ~ Handler a)
7170
=> a -> Server (SwaggerSchemaUI' dir api)
7271
jensolegSwaggerSchemaUIServer =
7372
swaggerSchemaUIServerImpl jensolegIndexTemplate jensolegFiles

servant-swagger-ui-redoc/CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
- 0.3.6.1.22.3
2+
- Generalize to support arbitrary type instead of hardcoded `Value`.
3+
4+
`SwaggerSchemaUI` now needs one more parameter which typically is
5+
either `Swagger` or `OpenApi`.
6+
7+
To migrate from older version, alter your API type from
8+
`SwaggerSchemaUI "swagger-ui" "swagger.json"`
9+
to
10+
`SwaggerSchemaUI "swagger-ui" "swagger.json" Swagger`
11+
12+
Or in case of the more generic variant, old
13+
`SwaggerSchemaUI' "foo-ui" ("foo" :> "swagger.json" :> Get '[JSON] Value)`
14+
becomes
15+
`SwaggerSchemaUI' "foo-ui" ("foo" :> "swagger.json" :> Get '[JSON] Swagger)`
16+
117
- 0.3.2.1.22.3
218
- Update to ReDoc-1.22.3
319

servant-swagger-ui-redoc/servant-swagger-ui-redoc.cabal

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 1.12
22
name: servant-swagger-ui-redoc
3-
version: 0.3.4.1.22.3
3+
version: 0.3.6.1.22.3
44
synopsis: Servant swagger ui: ReDoc theme
55
category: Web, Servant, Swagger
66
description:
@@ -36,10 +36,9 @@ source-repository head
3636
library
3737
hs-source-dirs: src
3838
ghc-options: -Wall
39-
build-depends: servant-swagger-ui-core >=0.3.5 && <0.4
39+
build-depends: servant-swagger-ui-core >=0.3.6 && <0.4
4040
build-depends:
4141
base >=4.7 && <4.17
42-
, aeson >=0.8.0.2 && <2.1.0
4342
, bytestring >=0.10.4.0 && <0.12
4443
, file-embed-lzma >=0 && <0.1
4544
, servant >=0.14 && <0.20

servant-swagger-ui-redoc/src/Servant/Swagger/UI/ReDoc.hs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ module Servant.Swagger.UI.ReDoc (
5757

5858
import Servant.Swagger.UI.Core
5959

60-
import Data.Aeson (ToJSON, Value)
6160
import Data.ByteString (ByteString)
6261
import Data.Text (Text)
6362
import FileEmbedLzma
@@ -67,7 +66,7 @@ import Servant
6766
--
6867
-- See <https://github.com/Rebilly/ReDoc/tree/v1.x>
6968
redocSchemaUIServer
70-
:: (Server api ~ Handler Value, ToJSON a)
69+
:: (Server api ~ Handler a)
7170
=> a -> Server (SwaggerSchemaUI' dir api)
7271
redocSchemaUIServer =
7372
swaggerSchemaUIServerImpl redocIndexTemplate redocFiles
@@ -80,7 +79,7 @@ redocSchemaUIServer =
8079
-- redocSchemaUIServerT :: Swagger -> ServerT (SwaggerSchemaUI schema dir) m
8180
-- @
8281
redocSchemaUIServerT
83-
:: (Monad m, ServerT api m ~ m Value, ToJSON a)
82+
:: (Monad m, ServerT api m ~ m a)
8483
=> a -> ServerT (SwaggerSchemaUI' dir api) m
8584
redocSchemaUIServerT =
8685
swaggerSchemaUIServerImpl redocIndexTemplate redocFiles

servant-swagger-ui/CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
- 0.3.6.4.5.0
2+
- Generalize to support arbitrary type instead of hardcoded `Value`.
3+
4+
`SwaggerSchemaUI` now needs one more parameter which typically is
5+
either `Swagger` or `OpenApi`.
6+
7+
To migrate from older version, alter your API type from
8+
`SwaggerSchemaUI "swagger-ui" "swagger.json"`
9+
to
10+
`SwaggerSchemaUI "swagger-ui" "swagger.json" Swagger`
11+
12+
Or in case of the more generic variant, old
13+
`SwaggerSchemaUI' "foo-ui" ("foo" :> "swagger.json" :> Get '[JSON] Value)`
14+
becomes
15+
`SwaggerSchemaUI' "foo-ui" ("foo" :> "swagger.json" :> Get '[JSON] Swagger)`
16+
117
- 0.3.5.3.47.1
218
- Update to `swagger-ui-3.47.1`
319
- Generalize `swaggerSchemaUIServer` to support arbitrary `Value` instead of hardcoded `Swagger`

0 commit comments

Comments
 (0)