@@ -0,0 +1,1115 @@
1+# Serving an API
2+
3+Enough chit-chat about type-level combinators and representing an API as a
4+type. Can we have a webservice already?
5+
6+## A first example
7+
8+Equipped with some basic knowledge about the way we represent APIs, let's now
9+write our first webservice.
10+
11+The source for this tutorial section is a literate haskell file, so first we
12+need to have some language extensions and imports:
13+
14+``` haskell
15+{-# LANGUAGE DataKinds #-}
16+{-# LANGUAGE DeriveGeneric #-}
17+{-# LANGUAGE FlexibleInstances #-}
18+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
19+{-# LANGUAGE MultiParamTypeClasses #-}
20+{-# LANGUAGE OverloadedStrings #-}
21+{-# LANGUAGE ScopedTypeVariables #-}
22+{-# LANGUAGE TypeOperators #-}
23+
24+module Server where
25+
26+import Prelude ()
27+import Prelude.Compat
28+
29+import Control.Monad.Except
30+import Control.Monad.Reader
31+import Data.Aeson.Compat
32+import Data.Aeson.Types
33+import Data.Attoparsec.ByteString
34+import Data.ByteString (ByteString)
35+import Data.List
36+import Data.Maybe
37+import Data.String.Conversions
38+import Data.Time.Calendar
39+import GHC.Generics
40+import Lucid
41+import Network.HTTP.Media ((//), (/:))
42+import Network.Wai
43+import Network.Wai.Handler.Warp
44+import Servant
45+import System.Directory
46+import Text.Blaze
47+import Text.Blaze.Html.Renderer.Utf8
48+import qualified Data.Aeson.Parser
49+import qualified Text.Blaze.Html
50+```
51+
52+**Important**: the `Servant` module comes from the **servant-server** package,
53+the one that lets us run webservers that implement a particular API type. It
54+reexports all the types from the **servant** package that let you declare API
55+types as well as everything you need to turn your request handlers into a
56+fully-fledged webserver. This means that in your applications, you can just add
57+**servant-server** as a dependency, import `Servant` and not worry about anything
58+else.
59+
60+We will write a server that will serve the following API.
61+
62+``` haskell
63+type UserAPI1 = "users" :> Get '[JSON] [User]
64+```
65+
66+Here's what we would like to see when making a GET request to `/users`.
67+
68+``` javascript
69+[ {"name": "Isaac Newton", "age": 372, "email": "isaac@newton.co.uk", "registration_date": "1683-03-01"}
70+, {"name": "Albert Einstein", "age": 136, "email": "ae@mc2.org", "registration_date": "1905-12-01"}
71+]
72+```
73+
74+Now let's define our `User` data type and write some instances for it.
75+
76+``` haskell
77+data User = User
78+ { name :: String
79+ , age :: Int
80+ , email :: String
81+ , registration_date :: Day
82+ } deriving (Eq, Show, Generic)
83+
84+instance ToJSON User
85+```
86+
87+Nothing funny going on here. But we now can define our list of two users.
88+
89+``` haskell
90+users1 :: [User]
91+users1 =
92+ [ User "Isaac Newton" 372 "isaac@newton.co.uk" (fromGregorian 1683 3 1)
93+ , User "Albert Einstein" 136 "ae@mc2.org" (fromGregorian 1905 12 1)
94+ ]
95+```
96+
97+Let's also write our API type.
98+
99+``` haskell ignore
100+type UserAPI1 = "users" :> Get '[JSON] [User]
101+```
102+
103+We can now take care of writing the actual webservice that will handle requests
104+to such an API. This one will be very simple, being reduced to just a single
105+endpoint. The type of the web application is determined by the API type,
106+through a *type family* named `Server`. (Type families are just functions that
107+take types as input and return types.) The `Server` type family will compute
108+the right type that a bunch of request handlers should have just from the
109+corresponding API type.
110+
111+The first thing to know about the `Server` type family is that behind the
112+scenes it will drive the routing, letting you focus only on the business
113+logic. The second thing to know is that for each endpoint, your handlers will
114+by default run in the `ExceptT ServantErr IO` monad. This is overridable very
115+easily, as explained near the end of this guide. Third thing, the type of the
116+value returned in that monad must be the same as the second argument of the
117+HTTP method combinator used for the corresponding endpoint. In our case, it
118+means we must provide a handler of type `ExceptT ServantErr IO [User]`. Well,
119+we have a monad, let's just `return` our list:
120+
121+``` haskell
122+server1 :: Server UserAPI1
123+server1 = return users1
124+```
125+
126+That's it. Now we can turn `server` into an actual webserver using
127+[wai](http://hackage.haskell.org/package/wai) and
128+[warp](http://hackage.haskell.org/package/warp):
129+
130+``` haskell
131+userAPI :: Proxy UserAPI1
132+userAPI = Proxy
133+
134+-- 'serve' comes from servant and hands you a WAI Application,
135+-- which you can think of as an "abstract" web application,
136+-- not yet a webserver.
137+app1 :: Application
138+app1 = serve userAPI server1
139+```
140+
141+The `userAPI` bit is, alas, boilerplate (we need it to guide type inference).
142+But that's about as much boilerplate as you get.
143+
144+And we're done! Let's run our webservice on the port 8081.
145+
146+``` haskell
147+main :: IO ()
148+main = run 8081 app1
149+```
150+
151+You can put this all into a file or just grab [servant's
152+repo](http://github.com/haskell-servant/servant) and look at the
153+*doc/tutorial* directory. This code (the source of this web page) is in
154+*doc/tutorial/Server.lhs*.
155+
156+If you run it, you can go to `http://localhost:8081/users` in your browser or
157+query it with curl and you see:
158+
159+``` bash
160+$ curl http://localhost:8081/users
161+[{"email":"isaac@newton.co.uk","registration_date":"1683-03-01","age":372,"name":"Isaac Newton"},{"email":"ae@mc2.org","registration_date":"1905-12-01","age":136,"name":"Albert Einstein"}]
162+```
163+
164+## More endpoints
165+
166+What if we want more than one endpoint? Let's add `/albert` and `/isaac` to
167+view the corresponding users encoded in JSON.
168+
169+``` haskell
170+type UserAPI2 = "users" :> Get '[JSON] [User]
171+ :<|> "albert" :> Get '[JSON] User
172+ :<|> "isaac" :> Get '[JSON] User
173+```
174+
175+And let's adapt our code a bit.
176+
177+``` haskell
178+isaac :: User
179+isaac = User "Isaac Newton" 372 "isaac@newton.co.uk" (fromGregorian 1683 3 1)
180+
181+albert :: User
182+albert = User "Albert Einstein" 136 "ae@mc2.org" (fromGregorian 1905 12 1)
183+
184+users2 :: [User]
185+users2 = [isaac, albert]
186+```
187+
188+Now, just like we separate the various endpoints in `UserAPI` with `:<|>`, we
189+are going to separate the handlers with `:<|>` too! They must be provided in
190+the same order as in in the API type.
191+
192+``` haskell
193+server2 :: Server UserAPI2
194+server2 = return users2
195+ :<|> return albert
196+ :<|> return isaac
197+```
198+
199+And that's it! You can run this example in the same way that we showed for
200+`server1` and check out the data available at `/users`, `/albert` and `/isaac`.
201+
202+## From combinators to handler arguments
203+
204+Fine, we can write trivial webservices easily, but none of the two above use
205+any "fancy" combinator from servant. Let's address this and use `QueryParam`,
206+`Capture` and `ReqBody` right away. You'll see how each occurence of these
207+combinators in an endpoint makes the corresponding handler receive an
208+argument of the appropriate type automatically. You don't have to worry about
209+manually looking up URL captures or query string parameters, or
210+decoding/encoding data from/to JSON. Never.
211+
212+We are going to use the following data types and functions to implement a
213+server for `API`.
214+
215+``` haskell
216+type API = "position" :> Capture "x" Int :> Capture "y" Int :> Get '[JSON] Position
217+ :<|> "hello" :> QueryParam "name" String :> Get '[JSON] HelloMessage
218+ :<|> "marketing" :> ReqBody '[JSON] ClientInfo :> Post '[JSON] Email
219+
220+data Position = Position
221+ { xCoord :: Int
222+ , yCoord :: Int
223+ } deriving Generic
224+
225+instance ToJSON Position
226+
227+newtype HelloMessage = HelloMessage { msg :: String }
228+ deriving Generic
229+
230+instance ToJSON HelloMessage
231+
232+data ClientInfo = ClientInfo
233+ { clientName :: String
234+ , clientEmail :: String
235+ , clientAge :: Int
236+ , clientInterestedIn :: [String]
237+ } deriving Generic
238+
239+instance FromJSON ClientInfo
240+instance ToJSON ClientInfo
241+
242+data Email = Email
243+ { from :: String
244+ , to :: String
245+ , subject :: String
246+ , body :: String
247+ } deriving Generic
248+
249+instance ToJSON Email
250+
251+emailForClient :: ClientInfo -> Email
252+emailForClient c = Email from' to' subject' body'
253+
254+ where from' = "great@company.com"
255+ to' = clientEmail c
256+ subject' = "Hey " ++ clientName c ++ ", we miss you!"
257+ body' = "Hi " ++ clientName c ++ ",\n\n"
258+ ++ "Since you've recently turned " ++ show (clientAge c)
259+ ++ ", have you checked out our latest "
260+ ++ intercalate ", " (clientInterestedIn c)
261+ ++ " products? Give us a visit!"
262+```
263+
264+We can implement handlers for the three endpoints:
265+
266+``` haskell
267+server3 :: Server API
268+server3 = position
269+ :<|> hello
270+ :<|> marketing
271+
272+ where position :: Int -> Int -> ExceptT ServantErr IO Position
273+ position x y = return (Position x y)
274+
275+ hello :: Maybe String -> ExceptT ServantErr IO HelloMessage
276+ hello mname = return . HelloMessage $ case mname of
277+ Nothing -> "Hello, anonymous coward"
278+ Just n -> "Hello, " ++ n
279+
280+ marketing :: ClientInfo -> ExceptT ServantErr IO Email
281+ marketing clientinfo = return (emailForClient clientinfo)
282+```
283+
284+Did you see that? The types for your handlers changed to be just what we
285+needed! In particular:
286+
287+ - a `Capture "something" a` becomes an argument of type `a` (for `position`);
288+ - a `QueryParam "something" a` becomes an argument of type `Maybe a` (because
289+an endpoint can technically be accessed without specifying any query
290+string parameter, we decided to "force" handlers to be aware that the
291+parameter might not always be there);
292+
293+ - a `ReqBody contentTypeList a` becomes an argument of type `a`;
294+
295+And that's it. Here's the example in action:
296+
297+``` bash
298+$ curl http://localhost:8081/position/1/2
299+{"xCoord":1,"yCoord":2}
300+$ curl http://localhost:8081/hello
301+{"msg":"Hello, anonymous coward"}
302+$ curl http://localhost:8081/hello?name=Alp
303+{"msg":"Hello, Alp"}
304+$ curl -X POST -d '{"clientName":"Alp Mestanogullari", "clientEmail" : "alp@foo.com", "clientAge": 25, "clientInterestedIn": ["haskell", "mathematics"]}' -H 'Accept: application/json' -H 'Content-type: application/json' http://localhost:8081/marketing
305+{"subject":"Hey Alp Mestanogullari, we miss you!","body":"Hi Alp Mestanogullari,\n\nSince you've recently turned 25, have you checked out our latest haskell, mathematics products? Give us a visit!","to":"alp@foo.com","from":"great@company.com"}
306+```
307+
308+For reference, here's a list of some combinators from **servant**:
309+
310+ > - `Delete`, `Get`, `Patch`, `Post`, `Put`: these do not become arguments. They provide the return type of handlers, which usually is `ExceptT ServantErr IO <something>`.
311+ > - `Capture "something" a` becomes an argument of type `a`.
312+ > - `QueryParam "something" a`, `Header "something" a` all become arguments of type `Maybe a`, because there might be no value at all specified by the client for these.
313+ > - `QueryFlag "something"` gets turned into an argument of type `Bool`.
314+ > - `QueryParams "something" a` gets turned into an argument of type `[a]`.
315+ > - `ReqBody contentTypes a` gets turned into an argument of type `a`.
316+
317+## The `FromHttpApiData`/`ToHttpApiData` classes
318+
319+Wait... How does **servant** know how to decode the `Int`s from the URL? Or how
320+to decode a `ClientInfo` value from the request body? This is what this and the
321+following two sections address.
322+
323+`Capture`s and `QueryParam`s are represented by some textual value in URLs.
324+`Header`s are similarly represented by a pair of a header name and a
325+corresponding (textual) value in the request's "metadata". How types are
326+decoded from headers, captures, and query params is expressed in a class
327+`FromHttpApiData` (from the package
328+[**http-api-data**](http://hackage.haskell.org/package/http-api-data)):
329+
330+``` haskell ignore
331+class FromHttpApiData a where
332+ {-# MINIMAL parseUrlPiece | parseQueryParam #-}
333+ -- | Parse URL path piece.
334+ parseUrlPiece :: Text -> Either Text a
335+ parseUrlPiece = parseQueryParam
336+
337+ -- | Parse HTTP header value.
338+ parseHeader :: ByteString -> Either Text a
339+ parseHeader = parseUrlPiece . decodeUtf8
340+
341+ -- | Parse query param value.
342+ parseQueryParam :: Text -> Either Text a
343+ parseQueryParam = parseUrlPiece
344+```
345+
346+As you can see, as long as you provide either `parseUrlPiece` (for `Capture`s)
347+or `parseQueryParam` (for `QueryParam`s), the other methods will be defined in
348+terms of this.
349+
350+**http-api-data** provides a decent number of instances, helpers for defining new
351+ones, and wonderful documentation.
352+
353+There's not much else to say about these classes. You will need instances for
354+them when using `Capture`, `QueryParam`, `QueryParams`, and `Header` with your
355+types. You will need `FromHttpApiData` instances for server-side request
356+handlers and `ToHttpApiData` instances only when using
357+**servant-client**, as described in the [section about deriving haskell
358+functions to query an API](Client.html).
359+
360+## Using content-types with your data types
361+
362+The same principle was operating when decoding request bodies from JSON, and
363+responses *into* JSON. (JSON is just the running example - you can do this with
364+any content-type.)
365+
366+This section introduces a couple of typeclasses provided by **servant** that make
367+all of this work.
368+
369+### The truth behind `JSON`
370+
371+
372+What exactly is `JSON` (the type as used in `Get '[JSON] User`)? Like the 3
373+other content-types provided out of the box by **servant**, it's a really dumb
374+data type.
375+
376+``` haskell ignore
377+data JSON
378+data PlainText
379+data FormUrlEncoded
380+data OctetStream
381+```
382+
383+Obviously, this is not all there is to `JSON`, otherwise it would be quite
384+pointless. Like most of the data types in **servant**, `JSON` is mostly there as
385+a special *symbol* that's associated with encoding (resp. decoding) to (resp.
386+from) the *JSON* format. The way this association is performed can be
387+decomposed into two steps.
388+
389+The first step is to provide a proper
390+`MediaType` (from
391+[**http-media**](https://hackage.haskell.org/package/http-media-0.6.2/docs/Network-HTTP-Media.html))
392+representation for `JSON`, or for your own content-types. If you look at the
393+haddocks from this link, you can see that we just have to specify
394+`application/json` using the appropriate functions. In our case, we can just
395+use `(//) :: ByteString -> ByteString -> MediaType`. The precise way to specify
396+the `MediaType` is to write an instance for the `Accept` class:
397+
398+``` haskell ignore
399+-- for reference:
400+class Accept ctype where
401+ contentType :: Proxy ctype -> MediaType
402+
403+instance Accept JSON where
404+ contentType _ = "application" // "json"
405+```
406+
407+The second step is centered around the `MimeRender` and `MimeUnrender` classes.
408+These classes just let you specify a way to encode and decode
409+values into or from your content-type's representation.
410+
411+``` haskell ignore
412+class Accept ctype => MimeRender ctype a where
413+ mimeRender :: Proxy ctype -> a -> ByteString
414+ -- alternatively readable as:
415+ mimeRender :: Proxy ctype -> (a -> ByteString)
416+```
417+
418+Given a content-type and some user type, `MimeRender` provides a function that
419+encodes values of type `a` to lazy `ByteString`s.
420+
421+In the case of `JSON`, this is easily dealt with! For any type `a` with a
422+`ToJSON` instance, we can render values of that type to JSON using
423+`Data.Aeson.encode`.
424+
425+``` haskell ignore
426+instance ToJSON a => MimeRender JSON a where
427+ mimeRender _ = encode
428+```
429+
430+And now the `MimeUnrender` class, which lets us extract values from lazy
431+`ByteString`s, alternatively failing with an error string.
432+
433+``` haskell ignore
434+class Accept ctype => MimeUnrender ctype a where
435+ mimeUnrender :: Proxy ctype -> ByteString -> Either String a
436+```
437+
438+We don't have much work to do there either, `Data.Aeson.eitherDecode` is
439+precisely what we need. However, it only allows arrays and objects as toplevel
440+JSON values and this has proven to get in our way more than help us so we wrote
441+our own little function around **aeson** and **attoparsec** that allows any type of
442+JSON value at the toplevel of a "JSON document". Here's the definition in case
443+you are curious.
444+
445+``` haskell
446+eitherDecodeLenient :: FromJSON a => ByteString -> Either String a
447+eitherDecodeLenient input = do
448+ v :: Value <- parseOnly (Data.Aeson.Parser.value <* endOfInput) (cs input)
449+ parseEither parseJSON v
450+```
451+
452+This function is exactly what we need for our `MimeUnrender` instance.
453+
454+``` haskell ignore
455+instance FromJSON a => MimeUnrender JSON a where
456+ mimeUnrender _ = eitherDecodeLenient
457+```
458+
459+And this is all the code that lets you use `JSON` with `ReqBody`, `Get`,
460+`Post` and friends. We can check our understanding by implementing support
461+for an `HTML` content-type, so that users of your webservice can access an
462+HTML representation of the data they want, ready to be included in any HTML
463+document, e.g. using [jQuery's `load` function](https://api.jquery.com/load/),
464+simply by adding `Accept: text/html` to their request headers.
465+
466+### Case-studies: **servant-blaze** and **servant-lucid**
467+
468+These days, most of the haskellers who write their HTML UIs directly from
469+Haskell use either [**blaze-html**](http://hackage.haskell.org/package/blaze-html)
470+or [**lucid**](http://hackage.haskell.org/package/lucid). The best option for
471+**servant** is obviously to support both (and hopefully other templating
472+solutions!). We're first going to look at **lucid**:
473+
474+``` haskell
475+data HTMLLucid
476+```
477+
478+Once again, the data type is just there as a symbol for the encoding/decoding
479+functions, except that this time we will only worry about encoding since
480+**lucid** doesn't provide a way to extract data from HTML.
481+
482+``` haskell
483+instance Accept HTMLLucid where
484+ contentType _ = "text" // "html" /: ("charset", "utf-8")
485+```
486+
487+Note that this instance uses the `(/:)` operator from **http-media** which lets
488+us specify additional information about a content-type, like the charset here.
489+
490+The rendering instances call similar functions that take
491+types with an appropriate instance to an "abstract" HTML representation and
492+then write that to a `ByteString`.
493+
494+``` haskell
495+instance ToHtml a => MimeRender HTMLLucid a where
496+ mimeRender _ = renderBS . toHtml
497+
498+-- let's also provide an instance for lucid's
499+-- 'Html' wrapper.
500+instance MimeRender HTMLLucid (Html a) where
501+ mimeRender _ = renderBS
502+```
503+
504+For **blaze-html** everything works very similarly:
505+
506+``` haskell
507+-- For this tutorial to compile 'HTMLLucid' and 'HTMLBlaze' have to be
508+-- distinct. Usually you would stick to one html rendering library and then
509+-- you can go with one 'HTML' type.
510+data HTMLBlaze
511+
512+instance Accept HTMLBlaze where
513+ contentType _ = "text" // "html" /: ("charset", "utf-8")
514+
515+instance ToMarkup a => MimeRender HTMLBlaze a where
516+ mimeRender _ = renderHtml . Text.Blaze.Html.toHtml
517+
518+-- while we're at it, just like for lucid we can
519+-- provide an instance for rendering blaze's 'Html' type
520+instance MimeRender HTMLBlaze Text.Blaze.Html.Html where
521+ mimeRender _ = renderHtml
522+```
523+
524+Both [**servant-blaze**](http://hackage.haskell.org/package/servant-blaze) and
525+[**servant-lucid**](http://hackage.haskell.org/package/servant-lucid) let you use
526+`HTMLLucid` and `HTMLBlaze` in any content-type list as long as you provide an instance of the
527+appropriate class (`ToMarkup` for **blaze-html**, `ToHtml` for **lucid**).
528+
529+We can now write a webservice that uses **servant-lucid** to show the `HTMLLucid`
530+content-type in action. We will be serving the following API:
531+
532+``` haskell
533+type PersonAPI = "persons" :> Get '[JSON, HTMLLucid] [Person]
534+```
535+
536+where `Person` is defined as follows:
537+
538+``` haskell
539+data Person = Person
540+ { firstName :: String
541+ , lastName :: String
542+ } deriving Generic -- for the JSON instance
543+
544+instance ToJSON Person
545+```
546+
547+Now, let's teach **lucid** how to render a `Person` as a row in a table, and then
548+a list of `Person`s as a table with a row per person.
549+
550+``` haskell
551+-- HTML serialization of a single person
552+instance ToHtml Person where
553+ toHtml person =
554+ tr_ $ do
555+ td_ (toHtml $ firstName person)
556+ td_ (toHtml $ lastName person)
557+
558+ -- do not worry too much about this
559+ toHtmlRaw = toHtml
560+
561+-- HTML serialization of a list of persons
562+instance ToHtml [Person] where
563+ toHtml persons = table_ $ do
564+ tr_ $ do
565+ th_ "first name"
566+ th_ "last name"
567+
568+ -- this just calls toHtml on each person of the list
569+ -- and concatenates the resulting pieces of HTML together
570+ foldMap toHtml persons
571+
572+ toHtmlRaw = toHtml
573+```
574+
575+We create some `Person` values and serve them as a list:
576+
577+``` haskell
578+people :: [Person]
579+people =
580+ [ Person "Isaac" "Newton"
581+ , Person "Albert" "Einstein"
582+ ]
583+
584+personAPI :: Proxy PersonAPI
585+personAPI = Proxy
586+
587+server4 :: Server PersonAPI
588+server4 = return people
589+
590+app2 :: Application
591+app2 = serve personAPI server4
592+```
593+
594+And we're good to go:
595+
596+``` bash
597+$ curl http://localhost:8081/persons
598+[{"lastName":"Newton","firstName":"Isaac"},{"lastName":"Einstein","firstName":"Albert"}]
599+$ curl -H 'Accept: text/html' http://localhost:8081/persons
600+<table><tr><td>first name</td><td>last name</td></tr><tr><td>Isaac</td><td>Newton</td></tr><tr><td>Albert</td><td>Einstein</td></tr></table>
601+# or just point your browser to http://localhost:8081/persons
602+```
603+
604+## The `ExceptT ServantErr IO` monad
605+
606+At the heart of the handlers is the monad they run in, namely `ExceptT
607+ServantErr IO`
608+([haddock documentation for `ExceptT`](http://hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-Except.html#t:ExceptT)).
609+One might wonder: why this monad? The answer is that it is the
610+simplest monad with the following properties:
611+
612+- it lets us both return a successful result (using `return`)
613+or "fail" with a descriptive error (using `throwError`);
614+- it lets us perform IO, which is absolutely vital since most webservices exist
615+as interfaces to databases that we interact with in `IO`.
616+
617+Let's recall some definitions.
618+
619+``` haskell ignore
620+-- from the 'mtl' package at
621+newtype ExceptT e m a = ExceptT (m (Either e a))
622+```
623+
624+In short, this means that a handler of type `ExceptT ServantErr IO a` is simply
625+equivalent to a computation of type `IO (Either ServantErr a)`, that is, an IO
626+action that either returns an error or a result.
627+
628+The module [`Control.Monad.Except`](https://hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-Except.html#t:ExceptT)
629+from which `ExceptT` comes is worth looking at.
630+Perhaps most importantly, `ExceptT` is an instance of `MonadError`, so
631+`throwError` can be used to return an error from your handler (whereas `return`
632+ is enough to return a success).
633+
634+Most of what you'll be doing in your handlers is running some IO and,
635+depending on the result, you might sometimes want to throw an error of some
636+kind and abort early. The next two sections cover how to do just that.
637+
638+### Performing IO
639+
640+Another important instance from the list above is `MonadIO m => MonadIO
641+(ExceptT e m)`.
642+[`MonadIO`](http://hackage.haskell.org/package/transformers-0.4.3.0/docs/Control-Monad-IO-Class.html)
643+is a class from the **transformers** package defined as:
644+
645+``` haskell ignore
646+class Monad m => MonadIO m where
647+ liftIO :: IO a -> m a
648+```
649+
650+The `IO` monad provides a `MonadIO` instance. Hence for any type
651+`e`, `ExceptT e IO` has a `MonadIO` instance. So if you want to run any kind of
652+IO computation in your handlers, just use `liftIO`:
653+
654+``` haskell
655+type IOAPI1 = "myfile.txt" :> Get '[JSON] FileContent
656+
657+newtype FileContent = FileContent
658+ { content :: String }
659+ deriving Generic
660+
661+instance ToJSON FileContent
662+
663+server5 :: Server IOAPI1
664+server5 = do
665+ filecontent <- liftIO (readFile "myfile.txt")
666+ return (FileContent filecontent)
667+```
668+
669+### Failing, through `ServantErr`
670+
671+If you want to explicitly fail at providing the result promised by an endpoint
672+using the appropriate HTTP status code (not found, unauthorized, etc) and some
673+error message, all you have to do is use the `throwError` function mentioned above
674+and provide it with the appropriate value of type `ServantErr`, which is
675+defined as:
676+
677+``` haskell ignore
678+data ServantErr = ServantErr
679+ { errHTTPCode :: Int
680+ , errReasonPhrase :: String
681+ , errBody :: ByteString -- lazy bytestring
682+ , errHeaders :: [Header]
683+ }
684+```
685+
686+Many standard values are provided out of the box by the `Servant.Server`
687+module. If you want to use these values but add a body or some headers, just
688+use record update syntax:
689+
690+``` haskell
691+failingHandler :: ExceptT ServantErr IO ()
692+failingHandler = throwError myerr
693+
694+ where myerr :: ServantErr
695+ myerr = err503 { errBody = "Sorry dear user." }
696+```
697+
698+Here's an example where we return a customised 404-Not-Found error message in
699+the response body if "myfile.txt" isn't there:
700+
701+``` haskell
702+server6 :: Server IOAPI1
703+server6 = do
704+ exists <- liftIO (doesFileExist "myfile.txt")
705+ if exists
706+ then liftIO (readFile "myfile.txt") >>= return . FileContent
707+ else throwError custom404Err
708+
709+ where custom404Err = err404 { errBody = "myfile.txt just isn't there, please leave this server alone." }
710+```
711+
712+Here's how that server looks in action:
713+
714+``` bash
715+$ curl --verbose http://localhost:8081/myfile.txt
716+[snip]
717+* Connected to localhost (127.0.0.1) port 8081 (#0)
718+> GET /myfile.txt HTTP/1.1
719+> User-Agent: curl/7.30.0
720+> Host: localhost:8081
721+> Accept: */*
722+>
723+< HTTP/1.1 404 Not Found
724+[snip]
725+myfile.txt just isnt there, please leave this server alone.
726+
727+$ echo Hello > myfile.txt
728+
729+$ curl --verbose http://localhost:8081/myfile.txt
730+[snip]
731+* Connected to localhost (127.0.0.1) port 8081 (#0)
732+> GET /myfile.txt HTTP/1.1
733+> User-Agent: curl/7.30.0
734+> Host: localhost:8081
735+> Accept: */*
736+>
737+< HTTP/1.1 200 OK
738+[snip]
739+< Content-Type: application/json
740+[snip]
741+{"content":"Hello\n"}
742+```
743+
744+## Response headers
745+
746+To add headers to your response, use
747+[addHeader](http://hackage.haskell.org/package/servant/docs/Servant-API-ResponseHeaders.html).
748+Note that this changes the type of your API, as we can see in the following example:
749+
750+``` haskell
751+type MyHandler = Get '[JSON] (Headers '[Header "X-An-Int" Int] User)
752+
753+myHandler :: Server MyHandler
754+myHandler = return $ addHeader 1797 albert
755+```
756+
757+Note that the type of `addHeader x` is different than the type of `x`!
758+
759+## Serving static files
760+
761+**servant-server** also provides a way to just serve the content of a directory
762+under some path in your web API. As mentioned earlier in this document, the
763+`Raw` combinator can be used in your APIs to mean "plug here any WAI
764+application". Well, **servant-server** provides a function to get a file and
765+directory serving WAI application, namely:
766+
767+``` haskell ignore
768+-- exported by Servant and Servant.Server
769+serveDirectory :: FilePath -> Server Raw
770+```
771+
772+`serveDirectory`'s argument must be a path to a valid directory.
773+
774+Here's an example API that will serve some static files:
775+
776+``` haskell
777+type StaticAPI = "static" :> Raw
778+```
779+
780+And the server:
781+
782+``` haskell
783+staticAPI :: Proxy StaticAPI
784+staticAPI = Proxy
785+```
786+
787+``` haskell
788+server7 :: Server StaticAPI
789+server7 = serveDirectory "static-files"
790+
791+app3 :: Application
792+app3 = serve staticAPI server7
793+```
794+
795+This server will match any request whose path starts with `/static` and will look
796+for a file at the path described by the rest of the request path, inside the
797+ *static-files/* directory of the path you run the program from.
798+
799+In other words: If a client requests `/static/foo.txt`, the server will look for a file at
800+`./static-files/foo.txt`. If that file exists it'll succeed and serve the file.
801+If it doesn't exist, the handler will fail with a `404` status code.
802+
803+## Nested APIs
804+
805+Let's see how you can define APIs in a modular way, while avoiding repetition.
806+Consider this simple example:
807+
808+``` haskell
809+type UserAPI3 = -- view the user with given userid, in JSON
810+ Capture "userid" Int :> Get '[JSON] User
811+
812+ :<|> -- delete the user with given userid. empty response
813+ Capture "userid" Int :> Delete '[] ()
814+```
815+
816+We can instead factor out the `userid`:
817+
818+``` haskell
819+type UserAPI4 = Capture "userid" Int :>
820+ ( Get '[JSON] User
821+ :<|> Delete '[] ()
822+ )
823+```
824+
825+However, you have to be aware that this has an effect on the type of the
826+corresponding `Server`:
827+
828+``` haskell ignore
829+Server UserAPI3 = (Int -> ExceptT ServantErr IO User)
830+ :<|> (Int -> ExceptT ServantErr IO ())
831+
832+Server UserAPI4 = Int -> ( ExceptT ServantErr IO User
833+ :<|> ExceptT ServantErr IO ()
834+ )
835+```
836+
837+In the first case, each handler receives the *userid* argument. In the latter,
838+the whole `Server` takes the *userid* and has handlers that are just
839+computations in `ExceptT`, with no arguments. In other words:
840+
841+``` haskell
842+server8 :: Server UserAPI3
843+server8 = getUser :<|> deleteUser
844+
845+ where getUser :: Int -> ExceptT ServantErr IO User
846+ getUser _userid = error "..."
847+
848+ deleteUser :: Int -> ExceptT ServantErr IO ()
849+ deleteUser _userid = error "..."
850+
851+-- notice how getUser and deleteUser
852+-- have a different type! no argument anymore,
853+-- the argument directly goes to the whole Server
854+server9 :: Server UserAPI4
855+server9 userid = getUser userid :<|> deleteUser userid
856+
857+ where getUser :: Int -> ExceptT ServantErr IO User
858+ getUser = error "..."
859+
860+ deleteUser :: Int -> ExceptT ServantErr IO ()
861+ deleteUser = error "..."
862+```
863+
864+Note that there's nothing special about `Capture` that lets you "factor it
865+out": this can be done with any combinator. Here are a few examples of APIs
866+with a combinator factored out for which we can write a perfectly valid
867+`Server`.
868+
869+``` haskell
870+-- we just factor out the "users" path fragment
871+type API1 = "users" :>
872+ ( Get '[JSON] [User] -- user listing
873+ :<|> Capture "userid" Int :> Get '[JSON] User -- view a particular user
874+ )
875+
876+-- we factor out the Request Body
877+type API2 = ReqBody '[JSON] User :>
878+ ( Get '[JSON] User -- just display the same user back, don't register it
879+ :<|> Post '[JSON] () -- register the user. empty response
880+ )
881+
882+-- we factor out a Header
883+type API3 = Header "Authorization" Token :>
884+ ( Get '[JSON] SecretData -- get some secret data, if authorized
885+ :<|> ReqBody '[JSON] SecretData :> Post '[] () -- add some secret data, if authorized
886+ )
887+
888+newtype Token = Token ByteString
889+newtype SecretData = SecretData ByteString
890+```
891+
892+This approach lets you define APIs modularly and assemble them all into one big
893+API type only at the end.
894+
895+``` haskell
896+type UsersAPI =
897+ Get '[JSON] [User] -- list users
898+ :<|> ReqBody '[JSON] User :> Post '[] () -- add a user
899+ :<|> Capture "userid" Int :>
900+ ( Get '[JSON] User -- view a user
901+ :<|> ReqBody '[JSON] User :> Put '[] () -- update a user
902+ :<|> Delete '[] () -- delete a user
903+ )
904+
905+usersServer :: Server UsersAPI
906+usersServer = getUsers :<|> newUser :<|> userOperations
907+
908+ where getUsers :: ExceptT ServantErr IO [User]
909+ getUsers = error "..."
910+
911+ newUser :: User -> ExceptT ServantErr IO ()
912+ newUser = error "..."
913+
914+ userOperations userid =
915+ viewUser userid :<|> updateUser userid :<|> deleteUser userid
916+
917+ where
918+ viewUser :: Int -> ExceptT ServantErr IO User
919+ viewUser = error "..."
920+
921+ updateUser :: Int -> User -> ExceptT ServantErr IO ()
922+ updateUser = error "..."
923+
924+ deleteUser :: Int -> ExceptT ServantErr IO ()
925+ deleteUser = error "..."
926+```
927+
928+``` haskell
929+type ProductsAPI =
930+ Get '[JSON] [Product] -- list products
931+ :<|> ReqBody '[JSON] Product :> Post '[] () -- add a product
932+ :<|> Capture "productid" Int :>
933+ ( Get '[JSON] Product -- view a product
934+ :<|> ReqBody '[JSON] Product :> Put '[] () -- update a product
935+ :<|> Delete '[] () -- delete a product
936+ )
937+
938+data Product = Product { productId :: Int }
939+
940+productsServer :: Server ProductsAPI
941+productsServer = getProducts :<|> newProduct :<|> productOperations
942+
943+ where getProducts :: ExceptT ServantErr IO [Product]
944+ getProducts = error "..."
945+
946+ newProduct :: Product -> ExceptT ServantErr IO ()
947+ newProduct = error "..."
948+
949+ productOperations productid =
950+ viewProduct productid :<|> updateProduct productid :<|> deleteProduct productid
951+
952+ where
953+ viewProduct :: Int -> ExceptT ServantErr IO Product
954+ viewProduct = error "..."
955+
956+ updateProduct :: Int -> Product -> ExceptT ServantErr IO ()
957+ updateProduct = error "..."
958+
959+ deleteProduct :: Int -> ExceptT ServantErr IO ()
960+ deleteProduct = error "..."
961+```
962+
963+``` haskell
964+type CombinedAPI = "users" :> UsersAPI
965+ :<|> "products" :> ProductsAPI
966+
967+server10 :: Server CombinedAPI
968+server10 = usersServer :<|> productsServer
969+```
970+
971+Finally, we can realize the user and product APIs are quite similar and
972+abstract that away:
973+
974+``` haskell
975+-- API for values of type 'a'
976+-- indexed by values of type 'i'
977+type APIFor a i =
978+ Get '[JSON] [a] -- list 'a's
979+ :<|> ReqBody '[JSON] a :> Post '[] () -- add an 'a'
980+ :<|> Capture "id" i :>
981+ ( Get '[JSON] a -- view an 'a' given its "identifier" of type 'i'
982+ :<|> ReqBody '[JSON] a :> Put '[] () -- update an 'a'
983+ :<|> Delete '[] () -- delete an 'a'
984+ )
985+
986+-- Build the appropriate 'Server'
987+-- given the handlers of the right type.
988+serverFor :: ExceptT ServantErr IO [a] -- handler for listing of 'a's
989+ -> (a -> ExceptT ServantErr IO ()) -- handler for adding an 'a'
990+ -> (i -> ExceptT ServantErr IO a) -- handler for viewing an 'a' given its identifier of type 'i'
991+ -> (i -> a -> ExceptT ServantErr IO ()) -- updating an 'a' with given id
992+ -> (i -> ExceptT ServantErr IO ()) -- deleting an 'a' given its id
993+ -> Server (APIFor a i)
994+serverFor = error "..."
995+-- implementation left as an exercise. contact us on IRC
996+-- or the mailing list if you get stuck!
997+```
998+
999+## Using another monad for your handlers
1000+
1001+Remember how `Server` turns combinators for HTTP methods into `ExceptT
1002+ServantErr IO`? Well, actually, there's more to that. `Server` is actually a
1003+simple type synonym.
1004+
1005+``` haskell ignore
1006+type Server api = ServerT api (ExceptT ServantErr IO)
1007+```
1008+
1009+`ServerT` is the actual type family that computes the required types for the
1010+handlers that's part of the `HasServer` class. It's like `Server` except that
1011+it takes another parameter which is the monad you want your handlers to run in,
1012+or more generally the return types of your handlers. This third parameter is
1013+used for specifying the return type of the handler for an endpoint, e.g when
1014+computing `ServerT (Get '[JSON] Person) SomeMonad`. The result would be
1015+`SomeMonad Person`.
1016+
1017+The first and main question one might have then is: how do we write handlers
1018+that run in another monad? How can we "bring back" the value from a given monad
1019+into something **servant** can understand?
1020+
1021+### Natural transformations
1022+
1023+If we have a function that gets us from an `m a` to an `n a`, for any `a`, what
1024+do we have?
1025+
1026+``` haskell ignore
1027+newtype m :~> n = Nat { unNat :: forall a. m a -> n a}
1028+```
1029+
1030+For example:
1031+
1032+``` haskell
1033+listToMaybeNat :: [] :~> Maybe
1034+listToMaybeNat = Nat listToMaybe -- from Data.Maybe
1035+```
1036+
1037+(`Nat` comes from "natural transformation", in case you're wondering.)
1038+
1039+So if you want to write handlers using another monad/type than `ExceptT
1040+ServantErr IO`, say the `Reader String` monad, the first thing you have to
1041+prepare is a function:
1042+
1043+``` haskell ignore
1044+readerToHandler :: Reader String :~> ExceptT ServantErr IO
1045+```
1046+
1047+Let's start with `readerToHandler'`. We obviously have to run the `Reader`
1048+computation by supplying it with a `String`, like `"hi"`. We get an `a` out
1049+from that and can then just `return` it into `ExceptT`. We can then just wrap
1050+that function with the `Nat` constructor to make it have the fancier type.
1051+
1052+``` haskell
1053+readerToHandler' :: forall a. Reader String a -> ExceptT ServantErr IO a
1054+readerToHandler' r = return (runReader r "hi")
1055+
1056+readerToHandler :: Reader String :~> ExceptT ServantErr IO
1057+readerToHandler = Nat readerToHandler'
1058+```
1059+
1060+We can write some simple webservice with the handlers running in `Reader String`.
1061+
1062+``` haskell
1063+type ReaderAPI = "a" :> Get '[JSON] Int
1064+ :<|> "b" :> Get '[JSON] String
1065+
1066+readerAPI :: Proxy ReaderAPI
1067+readerAPI = Proxy
1068+
1069+readerServerT :: ServerT ReaderAPI (Reader String)
1070+readerServerT = a :<|> b
1071+
1072+ where a :: Reader String Int
1073+ a = return 1797
1074+
1075+ b :: Reader String String
1076+ b = ask
1077+```
1078+
1079+We unfortunately can't use `readerServerT` as an argument of `serve`, because
1080+`serve` wants a `Server ReaderAPI`, i.e., with handlers running in `ExceptT
1081+ServantErr IO`. But there's a simple solution to this.
1082+
1083+### Enter `enter`
1084+
1085+That's right. We have just written `readerToHandler`, which is exactly what we
1086+would need to apply to all handlers to make the handlers have the
1087+right type for `serve`. Being cumbersome to do by hand, we provide a function
1088+`enter` which takes a natural transformation between two parametrized types `m`
1089+and `n` and a `ServerT someapi m`, and returns a `ServerT someapi n`.
1090+
1091+In our case, we can wrap up our little webservice by using `enter
1092+readerToHandler` on our handlers.
1093+
1094+``` haskell
1095+readerServer :: Server ReaderAPI
1096+readerServer = enter readerToHandler readerServerT
1097+
1098+app4 :: Application
1099+app4 = serve readerAPI readerServer
1100+```
1101+
1102+This is the webservice in action:
1103+
1104+``` bash
1105+$ curl http://localhost:8081/a
1106+1797
1107+$ curl http://localhost:8081/b
1108+"hi"
1109+```
1110+
1111+## Conclusion
1112+
1113+You're now equipped to write webservices/web-applications using
1114+**servant**. The rest of this document focuses on **servant-client**,
1115+**servant-js** and **servant-docs**.