Skip to content

Commit 09b2245

Browse files
committed
server/config: added more documentation
1 parent df09f86 commit 09b2245

File tree

5 files changed

+53
-13
lines changed

5 files changed

+53
-13
lines changed

servant-examples/wai-middleware/wai-middleware.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ server = return products
4141

4242
-- logStdout :: Middleware
4343
-- i.e, logStdout :: Application -> Application
44-
-- serve :: Proxy api -> Config a -> Server api -> Application
44+
-- serve :: Proxy api -> Config config -> Server api -> Application
4545
-- so applying a middleware is really as simple as
4646
-- applying a function to the result of 'serve'
4747
app :: Application

servant-server/src/Servant/Server.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ module Servant.Server
3838

3939
-- * Config
4040
, Config(..)
41+
, HasConfigEntry(getConfigEntry)
42+
-- ** NamedConfig
4143
, NamedConfig(..)
44+
, descendIntoNamedConfig
4245

4346
-- * Default error type
4447
, ServantErr(..)

servant-server/src/Servant/Server/Internal.hs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import Data.String (fromString)
3333
import Data.String.Conversions (cs, (<>))
3434
import Data.Text (Text)
3535
import Data.Typeable
36-
import GHC.Exts (Constraint)
3736
import GHC.TypeLits (KnownNat, KnownSymbol, natVal,
3837
symbolVal)
3938
import Network.HTTP.Types hiding (Header, ResponseHeaders)

servant-server/src/Servant/Server/Internal/Config.hs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,18 @@ module Servant.Server.Internal.Config where
1515
import Data.Proxy
1616
import GHC.TypeLits
1717

18-
-- | The entire configuration.
19-
data Config a where
18+
-- | When calling 'Servant.Server.serve' you have to supply a configuration
19+
-- value of type @'Config' configTypes@. This parameter is used to pass values
20+
-- to combinators. (It shouldn't be confused with general configuration
21+
-- parameters for your web app, like the port, etc.). If you don't use
22+
-- combinators that require any config entries, you can just pass 'EmptyConfig'.
23+
-- To create a config with entries, use the operator @(':.')@. The parameter of
24+
-- the type 'Config' is a type-level list reflecting the types of the contained
25+
-- config entries:
26+
--
27+
-- >>> :type True :. () :. EmptyConfig
28+
-- True :. () :. EmptyConfig :: Config '[Bool, ()]
29+
data Config configTypes where
2030
EmptyConfig :: Config '[]
2131
(:.) :: x -> Config xs -> Config (x ': xs)
2232
infixr 5 :.
@@ -33,6 +43,19 @@ instance Eq (Config '[]) where
3343
instance (Eq a, Eq (Config as)) => Eq (Config (a ': as)) where
3444
x1 :. y1 == x2 :. y2 = x1 == x2 && y1 == y2
3545

46+
-- | This class is used to access config entries in 'Config's. 'getConfigEntry'
47+
-- returns the first value where the type matches:
48+
--
49+
-- >>> getConfigEntry (True :. False :. EmptyConfig) :: Bool
50+
-- True
51+
--
52+
-- If the 'Config' does not contain an entry of the requested type, you'll get
53+
-- an error:
54+
--
55+
-- >>> getConfigEntry (True :. False :. EmptyConfig) :: String
56+
-- ...
57+
-- No instance for (HasConfigEntry '[] [Char])
58+
-- ...
3659
class HasConfigEntry (config :: [*]) (val :: *) where
3760
getConfigEntry :: Config config -> val
3861

@@ -46,9 +69,28 @@ instance OVERLAPPING_
4669

4770
-- * support for named subconfigs
4871

72+
-- | Normally config entries are accessed by their types. In case you need
73+
-- to have multiple values of the same type in your 'Config' and need to access
74+
-- them, we provide 'NamedConfig'. You can think of it as sub-namespaces for
75+
-- 'Config's.
4976
data NamedConfig (name :: Symbol) (subConfig :: [*])
5077
= NamedConfig (Config subConfig)
5178

79+
-- | 'descendIntoNamedConfig' allows you to access `NamedConfig's. Usually you
80+
-- won't have to use it yourself but instead use a combinator like
81+
-- 'Servant.API.WithNamedConfig.WithNamedConfig'.
82+
--
83+
-- This is how 'descendIntoNamedConfig' works:
84+
--
85+
-- >>> :set -XFlexibleContexts
86+
-- >>> let subConfig = True :. EmptyConfig
87+
-- >>> :type subConfig
88+
-- subConfig :: Config '[Bool]
89+
-- >>> let parentConfig = False :. (NamedConfig subConfig :: NamedConfig "subConfig" '[Bool]) :. EmptyConfig
90+
-- >>> :type parentConfig
91+
-- parentConfig :: Config '[Bool, NamedConfig "subConfig" '[Bool]]
92+
-- >>> descendIntoNamedConfig (Proxy :: Proxy "subConfig") parentConfig :: Config '[Bool]
93+
-- True :. EmptyConfig
5294
descendIntoNamedConfig :: forall config name subConfig .
5395
HasConfigEntry config (NamedConfig name subConfig) =>
5496
Proxy (name :: Symbol) -> Config config -> Config subConfig

servant/src/Servant/API/WithNamedConfig.hs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,16 @@ module Servant.API.WithNamedConfig where
66
import GHC.TypeLits
77

88
-- | 'WithNamedConfig' names a specific tagged configuration to use for the
9-
-- combinators in the API. For example:
9+
-- combinators in the API. (See also in @servant-server@,
10+
-- @Servant.Server.Config@.) For example:
1011
--
11-
-- > type UseNamedConfigAPI1 = WithNamedConfig "myConfig" '[String] (
12+
-- > type UseNamedConfigAPI = WithNamedConfig "myConfig" '[String] (
1213
-- > ReqBody '[JSON] Int :> Get '[JSON] Int)
1314
--
1415
-- Both the 'ReqBody' and 'Get' combinators will use the 'NamedConfig' with
15-
-- type tag "myConfig" as their configuration. In constrast, in (notice
16-
-- parentesizing):
16+
-- type tag "myConfig" as their configuration.
1717
--
18-
-- > type UseNamedConfigAPI2 = WithNamedConfig "myConfig" '[String] (
19-
-- > ReqBody '[JSON] Int) :> Get '[JSON] Int
20-
--
21-
-- Only the 'ReqBody' combinator will use this configuration, and 'Get' will
22-
-- maintain the default configuration.
18+
-- 'Config's are only relevant for @servant-server@.
2319
--
2420
-- For more information, see the tutorial.
2521
data WithNamedConfig (name :: Symbol) (subConfig :: [*]) subApi

0 commit comments

Comments
 (0)