@@ -1,9 +1,10 @@
1−{-# LANGUAGE ConstraintKinds #-}
1+{-# LANGUAGE ConstraintKinds #-}
2−{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE DataKinds #-}
3−{-# LANGUAGE FlexibleContexts #-}
3+{-# LANGUAGE FlexibleContexts #-}
4−{-# LANGUAGE RankNTypes #-}
4+{-# LANGUAGE RankNTypes #-}
5+{-# LANGUAGE ScopedTypeVariables #-}
5−{-# LANGUAGE TypeFamilies #-}
6+{-# LANGUAGE TypeFamilies #-}
6−{-# LANGUAGE TypeOperators #-}
7+{-# LANGUAGE TypeOperators #-}
8-- | This module lets you implement 'Server's for defined APIs. You'll
9-- | This module lets you implement 'Server's for defined APIs. You'll
9-- most likely just need 'serve'.
10-- most likely just need 'serve'.
@@ -11,6 +12,8 @@ module Servant.Server
11 ( -- * Run a wai application from an API
12 ( -- * Run a wai application from an API
13 , serveWithContext
14 , serveWithContext
15 , -- * Construct a wai Application from an API
18 , -- * Construct a wai Application from an API
16 toApplication
19 toApplication
@@ -128,6 +131,15 @@ import Servant.Server.UVerb
129-- * Implementing Servers
132-- * Implementing Servers
134+-- | Constraints that need to be satisfied on a context for it to be passed to 'serveWithContext'.
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
131-- | 'serve' allows you to implement an API and produce a wai 'Application'.
143-- | 'serve' allows you to implement an API and produce a wai 'Application'.
133-- Example:
145-- Example:
@@ -157,11 +169,21 @@ serve p = serveWithContext p EmptyContext
157-- 'defaultErrorFormatters' will always be appended to the end of the passed context,
169-- 'defaultErrorFormatters' will always be appended to the end of the passed context,
158-- but if you pass your own formatter, it will override the default one.
170-- but if you pass your own formatter, it will override the default one.
159serveWithContext :: ( HasServer api context
171serveWithContext :: ( HasServer api context
160− , HasContextEntry (context .++ DefaultErrorFormatters) ErrorFormatters )
172+ , ServerContext context
161 => Proxy api -> Context context -> Server api -> Application
174 => Proxy api -> Context context -> Server api -> Application
162−serveWithContext p context server =
175+serveWithContext p context = serveWithContextT p context id
177+-- | A general 'serve' function that allows you to pass a custom context and hoisting function to
178+-- apply on all routes.
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 =
163− toApplication (runRouter format404 (route p context (emptyDelayed (Route server))))
184+ toApplication (runRouter format404 (route p context (emptyDelayed router)))
186+ router = Route $ hoistServerWithContext p (Proxy :: Proxy context) toHandler server
165 format404 = notFoundErrorFormatter . getContextEntry . mkContextWithErrorFormatter $ context
187 format404 = notFoundErrorFormatter . getContextEntry . mkContextWithErrorFormatter $ context
167-- | Hoist server implementation.
189-- | Hoist server implementation.