|
1 |
| -{-# LANGUAGE ConstraintKinds #-} |
2 |
| -{-# LANGUAGE DataKinds #-} |
3 |
| -{-# LANGUAGE FlexibleContexts #-} |
4 |
| -{-# LANGUAGE RankNTypes #-} |
5 |
| -{-# LANGUAGE TypeFamilies #-} |
6 |
| -{-# LANGUAGE TypeOperators #-} |
| 1 | +{-# LANGUAGE ConstraintKinds #-} |
| 2 | +{-# LANGUAGE DataKinds #-} |
| 3 | +{-# LANGUAGE FlexibleContexts #-} |
| 4 | +{-# LANGUAGE RankNTypes #-} |
| 5 | +{-# LANGUAGE ScopedTypeVariables #-} |
| 6 | +{-# LANGUAGE TypeFamilies #-} |
| 7 | +{-# LANGUAGE TypeOperators #-} |
7 | 8 |
|
8 | 9 | -- | This module lets you implement 'Server's for defined APIs. You'll
|
9 | 10 | -- most likely just need 'serve'.
|
10 | 11 | module Servant.Server
|
11 | 12 | ( -- * Run a wai application from an API
|
12 | 13 | serve
|
13 | 14 | , serveWithContext
|
| 15 | + , serveWithContextT |
| 16 | + , ServerContext |
14 | 17 |
|
15 | 18 | , -- * Construct a wai Application from an API
|
16 | 19 | toApplication
|
@@ -128,6 +131,15 @@ import Servant.Server.UVerb
|
128 | 131 |
|
129 | 132 | -- * Implementing Servers
|
130 | 133 |
|
| 134 | +-- | Constraints that need to be satisfied on a context for it to be passed to 'serveWithContext'. |
| 135 | +-- |
| 136 | +-- Typically, this will add default context entries to the context. You shouldn't typically |
| 137 | +-- need to worry about these constraints, but if you write a helper function that wraps |
| 138 | +-- 'serveWithContext', you might need to include this constraint. |
| 139 | +type ServerContext context = |
| 140 | + ( HasContextEntry (context .++ DefaultErrorFormatters) ErrorFormatters |
| 141 | + ) |
| 142 | + |
131 | 143 | -- | 'serve' allows you to implement an API and produce a wai 'Application'.
|
132 | 144 | --
|
133 | 145 | -- Example:
|
@@ -157,11 +169,21 @@ serve p = serveWithContext p EmptyContext
|
157 | 169 | -- 'defaultErrorFormatters' will always be appended to the end of the passed context,
|
158 | 170 | -- but if you pass your own formatter, it will override the default one.
|
159 | 171 | serveWithContext :: ( HasServer api context
|
160 |
| - , HasContextEntry (context .++ DefaultErrorFormatters) ErrorFormatters ) |
| 172 | + , ServerContext context |
| 173 | + ) |
161 | 174 | => Proxy api -> Context context -> Server api -> Application
|
162 |
| -serveWithContext p context server = |
163 |
| - toApplication (runRouter format404 (route p context (emptyDelayed (Route server)))) |
| 175 | +serveWithContext p context = serveWithContextT p context id |
| 176 | + |
| 177 | +-- | A general 'serve' function that allows you to pass a custom context and hoisting function to |
| 178 | +-- apply on all routes. |
| 179 | +serveWithContextT :: |
| 180 | + forall api context m. |
| 181 | + (HasServer api context, ServerContext context) => |
| 182 | + Proxy api -> Context context -> (forall x. m x -> Handler x) -> ServerT api m -> Application |
| 183 | +serveWithContextT p context toHandler server = |
| 184 | + toApplication (runRouter format404 (route p context (emptyDelayed router))) |
164 | 185 | where
|
| 186 | + router = Route $ hoistServerWithContext p (Proxy :: Proxy context) toHandler server |
165 | 187 | format404 = notFoundErrorFormatter . getContextEntry . mkContextWithErrorFormatter $ context
|
166 | 188 |
|
167 | 189 | -- | Hoist server implementation.
|
|
0 commit comments