Skip to content

Commit 632c33a

Browse files
kosmikussorki
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. Follow-up to haskell-servant#89. Co-Authored-By: srk <[email protected]>
1 parent 2c8092b commit 632c33a

File tree

12 files changed

+73
-26
lines changed

12 files changed

+73
-26
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 & 1 deletion
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:

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,19 @@ 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)
5352
import Servant
5453
import Servant.HTML.Blaze (HTML)
5554
import Text.Blaze (ToMarkup (..))
55+
import Data.Kind (Type)
5656

5757
import qualified Data.Text as T
5858

5959
-- | Swagger schema + ui api.
6060
--
61-
-- @SwaggerSchemaUI "swagger-ui" "swagger.json"@ will result into following hierarchy:
61+
-- @SwaggerSchemaUI "swagger-ui" "swagger.json" Swagger@ will result into following hierarchy:
6262
--
6363
-- @
6464
-- \/swagger.json
@@ -67,10 +67,11 @@ import qualified Data.Text as T
6767
-- \/swagger-ui\/...
6868
-- @
6969
--
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)
70+
-- The third type parameter specifies which Haskell datatype contains the Swagger
71+
-- description. Typical instantiations are @Swagger@ from the @swagger2@ package,
72+
-- and @OpenApi@ from the @openapi3@ package.
73+
type SwaggerSchemaUI (dir :: Symbol) (schema :: Symbol) (ctype :: Type) =
74+
SwaggerSchemaUI' dir (schema :> Get '[JSON] ctype)
7475

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

105106
swaggerSchemaUIServerImpl
106-
:: (Monad m, ServerT api m ~ m Value, ToJSON a)
107+
:: (Monad m, ServerT api m ~ m a)
107108
=> T.Text -> [(FilePath, ByteString)]
108109
-> a -> ServerT (SwaggerSchemaUI' dir api) m
109110
swaggerSchemaUIServerImpl indexTemplate files swagger
110-
= swaggerSchemaUIServerImpl' indexTemplate files $ return $ toJSON swagger
111+
= swaggerSchemaUIServerImpl' indexTemplate files $ return swagger
111112

112113
-- | Use a custom server to serve the Swagger spec source.
113114
swaggerSchemaUIServerImpl'

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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 & 2 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:
@@ -83,7 +83,7 @@ source-repository head
8383
library
8484
hs-source-dirs: src
8585
ghc-options: -Wall
86-
build-depends: servant-swagger-ui-core >=0.3.5 && <0.4
86+
build-depends: servant-swagger-ui-core >=0.3.6 && <0.4
8787
build-depends:
8888
base >=4.7 && <4.19
8989
, aeson >=0.8.0.2 && <2.3

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 & 2 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:
@@ -37,7 +37,7 @@ source-repository head
3737
library
3838
hs-source-dirs: src
3939
ghc-options: -Wall
40-
build-depends: servant-swagger-ui-core >=0.3.5 && <0.4
40+
build-depends: servant-swagger-ui-core >=0.3.6 && <0.4
4141
build-depends:
4242
base >=4.7 && <4.19
4343
, aeson >=0.8.0.2 && <2.3

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.14.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.4.14.0
218
- Update to `swagger-ui-4.14.0`
319

0 commit comments

Comments
 (0)