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