A server for a :<|> b first tries to match the request again the route
+ represented by a and if it fails tries b. You must provide a request
+ handler for each route.
type MyApi = "books" :> Get [Book] -- GET /books
+ :<|> "books" :> ReqBody Book :> Post Book -- POST /books
+
+server :: Server MyApi
+server = listAllBooks :<|> postBook
+ where listAllBooks = ...
+ postBook book = ...
\ No newline at end of file
diff --git a/Servant-API-Capture.html b/Servant-API-Capture.html
new file mode 100644
index 00000000..30f0100e
--- /dev/null
+++ b/Servant-API-Capture.html
@@ -0,0 +1,15 @@
+Servant.API.Capture
If you use Capture in one of the endpoints for your API,
+ this automatically requires your server-side handler to be a function
+ that takes an argument of the type specified by the Capture.
+ This lets servant worry about getting it from the URL and turning
+ it into a value of the type you specify.
You can control how it'll be converted from Text to your type
+ by simply providing an instance of FromText for your type.
Example:
type MyApi = "books" :> Capture "isbn" Text :> Get Book
+
+server :: Server MyApi
+server = getBook
+ where getBook :: Text -> EitherT (Int, String) IO Book
+ getBook isbn = ...
\ No newline at end of file
diff --git a/Servant-API-Delete.html b/Servant-API-Delete.html
new file mode 100644
index 00000000..30c49f0d
--- /dev/null
+++ b/Servant-API-Delete.html
@@ -0,0 +1,13 @@
+Servant.API.Delete
If you have a Delete endpoint in your API,
+ the handler for this endpoint is meant to delete
+ a resource.
The code of the handler will, just like
+ for Get, Post and
+ Put, run in EitherT (Int, String) IO ().
+ The Int represents the status code and the String a message
+ to be returned. You can use left to
+ painlessly error out if the conditions for a successful deletion
+ are not met.
\ No newline at end of file
diff --git a/Servant-API-Get.html b/Servant-API-Get.html
new file mode 100644
index 00000000..3b3d294c
--- /dev/null
+++ b/Servant-API-Get.html
@@ -0,0 +1,12 @@
+Servant.API.Get
When implementing the handler for a Get endpoint,
+ just like for Delete, Post
+ and Put, the handler code runs in the
+ EitherT (Int, String) IO monad, where the Int represents
+ the status code and the String a message, returned in case of
+ failure. You can quite handily use left
+ to quickly fail if some conditions are not met.
If successfully returning a value, we just require that its type has
+ a ToJSON instance and servant takes care of encoding it for you,
+ yielding status code 200 along the way.
\ No newline at end of file
diff --git a/Servant-API-Post.html b/Servant-API-Post.html
new file mode 100644
index 00000000..3fe7bf2d
--- /dev/null
+++ b/Servant-API-Post.html
@@ -0,0 +1,17 @@
+Servant.API.Post
Endpoint for POST requests. The type variable represents the type of the
+ response body (not the request body, use RQBody for
+ that).
Example:
-- POST /books
+ -- with a JSON encoded Book as the request body
+ -- returning the just-created Book
+type MyApi = "books" :> ReqBody Book :> Post Book
When implementing the handler for a Post endpoint,
+ just like for Delete, Get
+ and Put, the handler code runs in the
+ EitherT (Int, String) IO monad, where the Int represents
+ the status code and the String a message, returned in case of
+ failure. You can quite handily use left
+ to quickly fail if some conditions are not met.
If successfully returning a value, we just require that its type has
+ a ToJSON instance and servant takes care of encoding it for you,
+ yielding status code 201 along the way.
\ No newline at end of file
diff --git a/Servant-API-Put.html b/Servant-API-Put.html
new file mode 100644
index 00000000..745cfe56
--- /dev/null
+++ b/Servant-API-Put.html
@@ -0,0 +1,15 @@
+Servant.API.Put
Endpoint for PUT requests, usually used to update a ressource.
+ The type a is the type of the response body that's returned.
Example:
-- PUT /books/:isbn
+-- with a Book as request body, returning the updated Book
+type MyApi = "books" :> Capture "isbn" Text :> ReqBody Book :> Put Book
When implementing the handler for a Put endpoint,
+ just like for Delete, Get
+ and Post, the handler code runs in the
+ EitherT (Int, String) IO monad, where the Int represents
+ the status code and the String a message, returned in case of
+ failure. You can quite handily use left
+ to quickly fail if some conditions are not met.
If successfully returning a value, we just require that its type has
+ a ToJSON instance and servant takes care of encoding it for you,
+ yielding status code 200 along the way.
\ No newline at end of file
diff --git a/Servant-API-QueryParam.html b/Servant-API-QueryParam.html
new file mode 100644
index 00000000..ff1ea9d7
--- /dev/null
+++ b/Servant-API-QueryParam.html
@@ -0,0 +1,45 @@
+Servant.API.QueryParam
If you use QueryParam "author" Text in one of the endpoints for your API,
+ this automatically requires your server-side handler to be a function
+ that takes an argument of type MaybeText.
This lets servant worry about looking it up in the query string
+ and turning it into a value of the type you specify, enclosed
+ in Maybe, because it may not be there and servant would then
+ hand you Nothing.
You can control how it'll be converted from Text to your type
+ by simply providing an instance of FromText for your type.
Example:
type MyApi = "books" :> QueryParam "author" Text :> Get [Book]
+
+server :: Server MyApi
+server = getBooksBy
+ where getBooksBy :: Maybe Text -> EitherT (Int, String) IO [Book]
+ getBooksBy Nothing = ...return all books...
+ getBooksBy (Just author) = ...return books by the given author...
Lookup the values associated to the sym query string parameter
+ and try to extract it as a value of type [a]. This is typically
+ meant to support query string parameters of the form
+ param[]=val1¶m[]=val2 and so on. Note that servant doesn't actually
+ require the []s and will fetch the values just fine with
+ param=val1¶m=val2, too.
Example:
-- /books?authors[]=<author1>&authors[]=<author2>&...
+type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]
If you use QueryParams "authors" Text in one of the endpoints for your API,
+ this automatically requires your server-side handler to be a function
+ that takes an argument of type [Text].
This lets servant worry about looking up 0 or more values in the query string
+ associated to authors and turning each of them into a value of
+ the type you specify.
You can control how the individual values are converted from Text to your type
+ by simply providing an instance of FromText for your type.
Example:
type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]
+
+server :: Server MyApi
+server = getBooksBy
+ where getBooksBy :: [Text] -> EitherT (Int, String) IO [Book]
+ getBooksBy authors = ...return all books by these authors...
Lookup a potentially value-less query string parameter
+ with boolean semantics. If the param sym is there without any value,
+ or if it's there with value "true" or "1", it's interpreted as True.
+ Otherwise, it's interpreted as False.
If you use QueryFlag "published" in one of the endpoints for your API,
+ this automatically requires your server-side handler to be a function
+ that takes an argument of type Bool.
Example:
type MyApi = "books" :> QueryFlag "published" :> Get [Book]
+
+server :: Server MyApi
+server = getBooks
+ where getBooks :: Bool -> EitherT (Int, String) IO [Book]
+ getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument...
\ No newline at end of file
diff --git a/Servant-API-Raw.html b/Servant-API-Raw.html
new file mode 100644
index 00000000..21834152
--- /dev/null
+++ b/Servant-API-Raw.html
@@ -0,0 +1,11 @@
+Servant.API.Raw
Endpoint for plugging in your own Wai Applications.
The given Application will get the request as received by the server, potentially with
+ a modified (stripped) pathInfo if the Application is being routed with :>.
In addition to just letting you plug in your existing WAI Applications,
+ this can also be used with serveDirectory to serve
+ static files stored in a particular directory on your filesystem, or to serve
+ your API's documentation with serveDocumentation.
\ No newline at end of file
diff --git a/Servant-API-ReqBody.html b/Servant-API-ReqBody.html
new file mode 100644
index 00000000..fa32de1a
--- /dev/null
+++ b/Servant-API-ReqBody.html
@@ -0,0 +1,14 @@
+Servant.API.ReqBody
If you use ReqBody in one of the endpoints for your API,
+ this automatically requires your server-side handler to be a function
+ that takes an argument of the type specified by ReqBody.
+ This lets servant worry about extracting it from the request and turning
+ it into a value of the type you specify.
type MyApi = "books" :> ReqBody Book :> Post Book
+
+server :: Server MyApi
+server = postBook
+ where postBook :: Book -> EitherT (Int, String) IO Book
+ postBook book = ...insert into your db...
\ No newline at end of file
diff --git a/Servant-API-Sub.html b/Servant-API-Sub.html
new file mode 100644
index 00000000..6376dd4a
--- /dev/null
+++ b/Servant-API-Sub.html
@@ -0,0 +1,56 @@
+Servant.API.Sub
If you use Capture in one of the endpoints for your API,
+ this automatically requires your server-side handler to be a function
+ that takes an argument of the type specified by the Capture.
+ This lets servant worry about getting it from the URL and turning
+ it into a value of the type you specify.
You can control how it'll be converted from Text to your type
+ by simply providing an instance of FromText for your type.
Example:
type MyApi = "books" :> Capture "isbn" Text :> Get Book
+
+server :: Server MyApi
+server = getBook
+ where getBook :: Text -> EitherT (Int, String) IO Book
+ getBook isbn = ...
If you use QueryFlag "published" in one of the endpoints for your API,
+ this automatically requires your server-side handler to be a function
+ that takes an argument of type Bool.
Example:
type MyApi = "books" :> QueryFlag "published" :> Get [Book]
+
+server :: Server MyApi
+server = getBooks
+ where getBooks :: Bool -> EitherT (Int, String) IO [Book]
+ getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument...
If you use QueryParams "authors" Text in one of the endpoints for your API,
+ this automatically requires your server-side handler to be a function
+ that takes an argument of type [Text].
This lets servant worry about looking up 0 or more values in the query string
+ associated to authors and turning each of them into a value of
+ the type you specify.
You can control how the individual values are converted from Text to your type
+ by simply providing an instance of FromText for your type.
Example:
type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]
+
+server :: Server MyApi
+server = getBooksBy
+ where getBooksBy :: [Text] -> EitherT (Int, String) IO [Book]
+ getBooksBy authors = ...return all books by these authors...
If you use QueryParam "author" Text in one of the endpoints for your API,
+ this automatically requires your server-side handler to be a function
+ that takes an argument of type MaybeText.
This lets servant worry about looking it up in the query string
+ and turning it into a value of the type you specify, enclosed
+ in Maybe, because it may not be there and servant would then
+ hand you Nothing.
You can control how it'll be converted from Text to your type
+ by simply providing an instance of FromText for your type.
Example:
type MyApi = "books" :> QueryParam "author" Text :> Get [Book]
+
+server :: Server MyApi
+server = getBooksBy
+ where getBooksBy :: Maybe Text -> EitherT (Int, String) IO [Book]
+ getBooksBy Nothing = ...return all books...
+ getBooksBy (Just author) = ...return books by the given author...
If you use ReqBody in one of the endpoints for your API,
+ this automatically requires your server-side handler to be a function
+ that takes an argument of the type specified by ReqBody.
+ This lets servant worry about extracting it from the request and turning
+ it into a value of the type you specify.
type MyApi = "books" :> ReqBody Book :> Post Book
+
+server :: Server MyApi
+server = postBook
+ where postBook :: Book -> EitherT (Int, String) IO Book
+ postBook book = ...insert into your db...
\ No newline at end of file
diff --git a/Servant-API.html b/Servant-API.html
new file mode 100644
index 00000000..de67263d
--- /dev/null
+++ b/Servant-API.html
@@ -0,0 +1,4 @@
+Servant.API
\ No newline at end of file
diff --git a/Servant-Common-Text.html b/Servant-Common-Text.html
new file mode 100644
index 00000000..8ce17b95
--- /dev/null
+++ b/Servant-Common-Text.html
@@ -0,0 +1,7 @@
+Servant.Common.Text
\ No newline at end of file
diff --git a/Servant-QQ.html b/Servant-QQ.html
new file mode 100644
index 00000000..0f12ce8c
--- /dev/null
+++ b/Servant-QQ.html
@@ -0,0 +1,17 @@
+Servant.QQ
Finally-tagless encoding for our DSL.
+ Keeping repr' and repr distinct when writing functions with an
+ ExpSYM context ensures certain invariants (for instance, that there is
+ only one of get, post, put, and delete in a value), but
+ sometimes requires a little more work.
Comments are allowed, and have the standard Haskell format
-- for inline
{- ... -} for block
\ No newline at end of file
diff --git a/Servant-Server.html b/Servant-Server.html
new file mode 100644
index 00000000..c52cc4ae
--- /dev/null
+++ b/Servant-Server.html
@@ -0,0 +1,116 @@
+Servant.Server
If you have a Delete endpoint in your API,
+ the handler for this endpoint is meant to delete
+ a resource.
The code of the handler will, just like
+ for Get, Post and
+ Put, run in EitherT (Int, String) IO ().
+ The Int represents the status code and the String a message
+ to be returned. You can use left to
+ painlessly error out if the conditions for a successful deletion
+ are not met.
When implementing the handler for a Get endpoint,
+ just like for Delete, Post
+ and Put, the handler code runs in the
+ EitherT (Int, String) IO monad, where the Int represents
+ the status code and the String a message, returned in case of
+ failure. You can quite handily use left
+ to quickly fail if some conditions are not met.
If successfully returning a value, we just require that its type has
+ a ToJSON instance and servant takes care of encoding it for you,
+ yielding status code 200 along the way.
When implementing the handler for a Post endpoint,
+ just like for Delete, Get
+ and Put, the handler code runs in the
+ EitherT (Int, String) IO monad, where the Int represents
+ the status code and the String a message, returned in case of
+ failure. You can quite handily use left
+ to quickly fail if some conditions are not met.
If successfully returning a value, we just require that its type has
+ a ToJSON instance and servant takes care of encoding it for you,
+ yielding status code 201 along the way.
When implementing the handler for a Put endpoint,
+ just like for Delete, Get
+ and Post, the handler code runs in the
+ EitherT (Int, String) IO monad, where the Int represents
+ the status code and the String a message, returned in case of
+ failure. You can quite handily use left
+ to quickly fail if some conditions are not met.
If successfully returning a value, we just require that its type has
+ a ToJSON instance and servant takes care of encoding it for you,
+ yielding status code 200 along the way.
A server for a :<|> b first tries to match the request again the route
+ represented by a and if it fails tries b. You must provide a request
+ handler for each route.
type MyApi = "books" :> Get [Book] -- GET /books
+ :<|> "books" :> ReqBody Book :> Post Book -- POST /books
+
+server :: Server MyApi
+server = listAllBooks :<|> postBook
+ where listAllBooks = ...
+ postBook book = ...
If you use Capture in one of the endpoints for your API,
+ this automatically requires your server-side handler to be a function
+ that takes an argument of the type specified by the Capture.
+ This lets servant worry about getting it from the URL and turning
+ it into a value of the type you specify.
You can control how it'll be converted from Text to your type
+ by simply providing an instance of FromText for your type.
Example:
type MyApi = "books" :> Capture "isbn" Text :> Get Book
+
+server :: Server MyApi
+server = getBook
+ where getBook :: Text -> EitherT (Int, String) IO Book
+ getBook isbn = ...
If you use QueryFlag "published" in one of the endpoints for your API,
+ this automatically requires your server-side handler to be a function
+ that takes an argument of type Bool.
Example:
type MyApi = "books" :> QueryFlag "published" :> Get [Book]
+
+server :: Server MyApi
+server = getBooks
+ where getBooks :: Bool -> EitherT (Int, String) IO [Book]
+ getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument...
If you use QueryParams "authors" Text in one of the endpoints for your API,
+ this automatically requires your server-side handler to be a function
+ that takes an argument of type [Text].
This lets servant worry about looking up 0 or more values in the query string
+ associated to authors and turning each of them into a value of
+ the type you specify.
You can control how the individual values are converted from Text to your type
+ by simply providing an instance of FromText for your type.
Example:
type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]
+
+server :: Server MyApi
+server = getBooksBy
+ where getBooksBy :: [Text] -> EitherT (Int, String) IO [Book]
+ getBooksBy authors = ...return all books by these authors...
If you use QueryParam "author" Text in one of the endpoints for your API,
+ this automatically requires your server-side handler to be a function
+ that takes an argument of type MaybeText.
This lets servant worry about looking it up in the query string
+ and turning it into a value of the type you specify, enclosed
+ in Maybe, because it may not be there and servant would then
+ hand you Nothing.
You can control how it'll be converted from Text to your type
+ by simply providing an instance of FromText for your type.
Example:
type MyApi = "books" :> QueryParam "author" Text :> Get [Book]
+
+server :: Server MyApi
+server = getBooksBy
+ where getBooksBy :: Maybe Text -> EitherT (Int, String) IO [Book]
+ getBooksBy Nothing = ...return all books...
+ getBooksBy (Just author) = ...return books by the given author...
If you use ReqBody in one of the endpoints for your API,
+ this automatically requires your server-side handler to be a function
+ that takes an argument of the type specified by ReqBody.
+ This lets servant worry about extracting it from the request and turning
+ it into a value of the type you specify.
type MyApi = "books" :> ReqBody Book :> Post Book
+
+server :: Server MyApi
+server = postBook
+ where postBook :: Book -> EitherT (Int, String) IO Book
+ postBook book = ...insert into your db...
Make sure the incoming request starts with "/path", strip it and
+ pass the rest of the request path to sublayout.
\ No newline at end of file
diff --git a/Servant-Utils-Links.html b/Servant-Utils-Links.html
new file mode 100644
index 00000000..1a0ddc64
--- /dev/null
+++ b/Servant-Utils-Links.html
@@ -0,0 +1,23 @@
+Servant.Utils.Links
type API = Proxy ("hello" :> Get Int
+ :| "bye" :> QueryParam "name" String :> Post Bool)
+
+ api :: API
+ api = proxy
+
+ link1 :: Proxy ("hello" :> Get Int)
+ link1 = proxy
+
+ link2 :: Proxy ("hello" :> Delete)
+ link2 = proxy
+
+ mkLink link1 API -- typechecks, returns 'Link "/hello"'
+
+ mkLink link2 API -- doesn't typecheck
+
That is, mkLink takes two arguments, a link proxy and a sitemap, and
+ returns a Link, but only typechecks if the link proxy is a valid link,
+ and part of the sitemap.
N.B.:mkLink assumes a capture matches any string (without slashes).
\ No newline at end of file
diff --git a/Servant-Utils-StaticFiles.html b/Servant-Utils-StaticFiles.html
new file mode 100644
index 00000000..8198ec69
--- /dev/null
+++ b/Servant-Utils-StaticFiles.html
@@ -0,0 +1,15 @@
+Servant.Utils.StaticFiles
Serve anything under the specified directory as a Raw endpoint.
type MyApi = "static" :> Raw
+
+server :: Server MyApi
+server = serveDirectory "/var/www"
+
would capture any request to /static/<something> and look for
+ <something> under /var/www.
It will do its best to guess the MIME type for that file, based on the extension,
+ and send an appropriate Content-Type header if possible.
If your goal is to serve HTML, CSS and Javascript files that use the rest of the API
+ as a webapp backend, you will most likely not want the static files to be hidden
+ behind a /static/ prefix. In that case, remember to put the serveDirectory
+ handler in the last position, because servant will try to match the handlers
+ in order.
\ No newline at end of file
diff --git a/Servant.html b/Servant.html
new file mode 100644
index 00000000..6a794a2c
--- /dev/null
+++ b/Servant.html
@@ -0,0 +1,6 @@
+Servant
This module and its submodules can be used to define servant APIs. Note
+ that these API definitions don't directly implement a server (or anything
+ else).
\ No newline at end of file
diff --git a/doc-index.html b/doc-index.html
new file mode 100644
index 00000000..1187dac7
--- /dev/null
+++ b/doc-index.html
@@ -0,0 +1,4 @@
+servant-0.2 (Index)
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 00000000..d18ea030
--- /dev/null
+++ b/index.html
@@ -0,0 +1,4 @@
+servant-0.2
\ No newline at end of file
diff --git a/mini_Servant-API-Alternative.html b/mini_Servant-API-Alternative.html
new file mode 100644
index 00000000..5e2e0937
--- /dev/null
+++ b/mini_Servant-API-Alternative.html
@@ -0,0 +1,4 @@
+Servant.API.Alternative
\ No newline at end of file
diff --git a/mini_Servant-API-Capture.html b/mini_Servant-API-Capture.html
new file mode 100644
index 00000000..f2ad8622
--- /dev/null
+++ b/mini_Servant-API-Capture.html
@@ -0,0 +1,4 @@
+Servant.API.Capture
\ No newline at end of file
diff --git a/mini_Servant-API-Delete.html b/mini_Servant-API-Delete.html
new file mode 100644
index 00000000..5b11363c
--- /dev/null
+++ b/mini_Servant-API-Delete.html
@@ -0,0 +1,4 @@
+Servant.API.Delete
\ No newline at end of file
diff --git a/mini_Servant-API-Get.html b/mini_Servant-API-Get.html
new file mode 100644
index 00000000..03e9ebf4
--- /dev/null
+++ b/mini_Servant-API-Get.html
@@ -0,0 +1,4 @@
+Servant.API.Get
\ No newline at end of file
diff --git a/mini_Servant-API-Post.html b/mini_Servant-API-Post.html
new file mode 100644
index 00000000..7ed013a8
--- /dev/null
+++ b/mini_Servant-API-Post.html
@@ -0,0 +1,4 @@
+Servant.API.Post
\ No newline at end of file
diff --git a/mini_Servant-API-Put.html b/mini_Servant-API-Put.html
new file mode 100644
index 00000000..0a39d3b1
--- /dev/null
+++ b/mini_Servant-API-Put.html
@@ -0,0 +1,4 @@
+Servant.API.Put
\ No newline at end of file
diff --git a/mini_Servant-API-QueryParam.html b/mini_Servant-API-QueryParam.html
new file mode 100644
index 00000000..5016b335
--- /dev/null
+++ b/mini_Servant-API-QueryParam.html
@@ -0,0 +1,4 @@
+Servant.API.QueryParam
\ No newline at end of file
diff --git a/mini_Servant-API-Raw.html b/mini_Servant-API-Raw.html
new file mode 100644
index 00000000..5450dc62
--- /dev/null
+++ b/mini_Servant-API-Raw.html
@@ -0,0 +1,4 @@
+Servant.API.Raw
\ No newline at end of file
diff --git a/mini_Servant-API-ReqBody.html b/mini_Servant-API-ReqBody.html
new file mode 100644
index 00000000..20ba5bb2
--- /dev/null
+++ b/mini_Servant-API-ReqBody.html
@@ -0,0 +1,4 @@
+Servant.API.ReqBody
\ No newline at end of file
diff --git a/mini_Servant-API-Sub.html b/mini_Servant-API-Sub.html
new file mode 100644
index 00000000..079f2e46
--- /dev/null
+++ b/mini_Servant-API-Sub.html
@@ -0,0 +1,4 @@
+Servant.API.Sub
\ No newline at end of file
diff --git a/mini_Servant-API.html b/mini_Servant-API.html
new file mode 100644
index 00000000..0e8aa4d6
--- /dev/null
+++ b/mini_Servant-API.html
@@ -0,0 +1,4 @@
+Servant.API
Servant.API
Combinators
Accessing information from the request
Actual endpoints, distinguished by HTTP method
Untyped endpoints
Utilities
\ No newline at end of file
diff --git a/mini_Servant-Common-Text.html b/mini_Servant-Common-Text.html
new file mode 100644
index 00000000..5961e8df
--- /dev/null
+++ b/mini_Servant-Common-Text.html
@@ -0,0 +1,4 @@
+Servant.Common.Text
\ No newline at end of file
diff --git a/mini_Servant-QQ.html b/mini_Servant-QQ.html
new file mode 100644
index 00000000..874d956d
--- /dev/null
+++ b/mini_Servant-QQ.html
@@ -0,0 +1,4 @@
+Servant.QQ
\ No newline at end of file
diff --git a/mini_Servant-Server.html b/mini_Servant-Server.html
new file mode 100644
index 00000000..752cd3c9
--- /dev/null
+++ b/mini_Servant-Server.html
@@ -0,0 +1,4 @@
+Servant.Server
\ No newline at end of file
diff --git a/mini_Servant-Utils-Links.html b/mini_Servant-Utils-Links.html
new file mode 100644
index 00000000..b8816028
--- /dev/null
+++ b/mini_Servant-Utils-Links.html
@@ -0,0 +1,4 @@
+Servant.Utils.Links
\ No newline at end of file
diff --git a/mini_Servant-Utils-StaticFiles.html b/mini_Servant-Utils-StaticFiles.html
new file mode 100644
index 00000000..c8ebe5f6
--- /dev/null
+++ b/mini_Servant-Utils-StaticFiles.html
@@ -0,0 +1,4 @@
+Servant.Utils.StaticFiles
\ No newline at end of file
diff --git a/mini_Servant.html b/mini_Servant.html
new file mode 100644
index 00000000..9e47337d
--- /dev/null
+++ b/mini_Servant.html
@@ -0,0 +1,4 @@
+Servant
+-- type MyApi = "books" :> Get [Book] -- GET /books
+-- :<|> "books" :> ReqBody Book :> Post Book -- POST /books
+--
+-- server :: Server MyApi
+-- server = listAllBooks :<|> postBook
+-- where listAllBooks = ...
+-- postBook book = ...
+--
+-- app :: Application
+-- app = serve myApi server
+--
+-- main :: IO ()
+-- main = Network.Wai.Handler.Warp.run 8080 app
+--
+serve :: HasServer layout => Proxy layout -> Server layout -> Application
+toApplication :: RoutingApplication -> Application
+data RouteMismatch
+
+-- | the usual "not found" error
+NotFound :: RouteMismatch
+
+-- | a more informative "you just got the HTTP method wrong" error
+WrongMethod :: RouteMismatch
+
+-- | an even more informative "your json request body wasn't valid" error
+InvalidBody :: RouteMismatch
+
+-- |
+
+-- | A wrapper around EitherRouteMismatch a.
+newtype RouteResult a
+RR :: Either RouteMismatch a -> RouteResult a
+routeResult :: RouteResult a -> Either RouteMismatch a
+failWith :: RouteMismatch -> RouteResult a
+succeedWith :: a -> RouteResult a
+isMismatch :: RouteResult a -> Bool
+
+-- | If we get a Right, it has precedence over everything else.
+--
+-- This in particular means that if we could get several Rights,
+-- only the first we encounter would be taken into account.
+type RoutingApplication = Request -> (RouteResult Response -> IO ResponseReceived) -> IO ResponseReceived
+class HasServer layout where type family Server layout :: *
+route :: HasServer layout => Proxy layout -> Server layout -> RoutingApplication
+instance Eq RouteMismatch
+instance Show RouteMismatch
+instance Eq a => Eq (RouteResult a)
+instance Show a => Show (RouteResult a)
+instance Monoid (RouteResult a)
+instance Monoid RouteMismatch
+
+module Servant.API.Sub
+
+-- | The contained API (second argument) can be found under ("/" ++
+-- path) (path being the first argument).
+--
+-- Example:
+--
+--
+-- -- GET /hello/world
+-- -- returning a JSON encoded World value
+-- type MyApi = "hello" :> "world" :> Get World
+--
+data (:>) (path :: k) a
+(:>) :: Proxy path -> a -> (:>) a
+
+-- | Make sure the incoming request starts with "/path", strip it
+-- and pass the rest of the request path to sublayout.
+instance (KnownSymbol path, HasServer sublayout) => HasServer (path :> sublayout)
+
+module Servant.API.Alternative
+
+-- | Union of two APIs, first takes precedence in case of overlap.
+--
+-- Example:
+--
+--
+-- type MyApi = "books" :> Get [Book] -- GET /books
+-- :<|> "books" :> ReqBody Book :> Post Book -- POST /books
+--
+data (:<|>) a b
+(:<|>) :: a -> b -> (:<|>) a b
+
+-- | A server for a :<|> b first tries to match the
+-- request again the route represented by a and if it fails
+-- tries b. You must provide a request handler for each route.
+--
+--
+-- type MyApi = "books" :> Get [Book] -- GET /books
+-- :<|> "books" :> ReqBody Book :> Post Book -- POST /books
+--
+-- server :: Server MyApi
+-- server = listAllBooks :<|> postBook
+-- where listAllBooks = ...
+-- postBook book = ...
+--
+instance (HasServer a, HasServer b) => HasServer (a :<|> b)
+
+module Servant.API.Capture
+
+-- | Capture a value from the request path under a certain type a.
+--
+-- Example:
+--
+--
+-- -- GET /books/:isbn
+-- type MyApi = "books" :> Capture "isbn" Text :> Get Book
+--
+data Capture sym a
+instance (KnownSymbol capture, FromText a, HasServer sublayout) => HasServer (Capture capture a :> sublayout)
+
+module Servant.API.QueryParam
+
+-- | Lookup the value associated to the sym query string parameter
+-- and try to extract it as a value of type a.
+--
+-- Example:
+--
+--
+-- -- /books?author=<author name>
+-- type MyApi = "books" :> QueryParam "author" Text :> Get [Book]
+--
+data QueryParam sym a
+
+-- | If you use QueryParam "author" Text in one of the
+-- endpoints for your API, this automatically requires your server-side
+-- handler to be a function that takes an argument of type
+-- MaybeText.
+--
+-- This lets servant worry about looking it up in the query string and
+-- turning it into a value of the type you specify, enclosed in
+-- Maybe, because it may not be there and servant would then hand
+-- you Nothing.
+--
+-- You can control how it'll be converted from Text to your type
+-- by simply providing an instance of FromText for your type.
+--
+-- Example:
+--
+--
+-- type MyApi = "books" :> QueryParam "author" Text :> Get [Book]
+--
+-- server :: Server MyApi
+-- server = getBooksBy
+-- where getBooksBy :: Maybe Text -> EitherT (Int, String) IO [Book]
+-- getBooksBy Nothing = ...return all books...
+-- getBooksBy (Just author) = ...return books by the given author...
+--
+
+-- | Lookup the values associated to the sym query string
+-- parameter and try to extract it as a value of type [a]. This
+-- is typically meant to support query string parameters of the form
+-- param[]=val1¶m[]=val2 and so on. Note that servant
+-- doesn't actually require the []s and will fetch the values
+-- just fine with param=val1¶m=val2, too.
+--
+-- Example:
+--
+--
+-- -- /books?authors[]=<author1>&authors[]=<author2>&...
+-- type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]
+--
+data QueryParams sym a
+
+-- | If you use QueryParams "authors" Text in one of the
+-- endpoints for your API, this automatically requires your server-side
+-- handler to be a function that takes an argument of type
+-- [Text].
+--
+-- This lets servant worry about looking up 0 or more values in the query
+-- string associated to authors and turning each of them into a
+-- value of the type you specify.
+--
+-- You can control how the individual values are converted from
+-- Text to your type by simply providing an instance of
+-- FromText for your type.
+--
+-- Example:
+--
+--
+-- type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]
+--
+-- server :: Server MyApi
+-- server = getBooksBy
+-- where getBooksBy :: [Text] -> EitherT (Int, String) IO [Book]
+-- getBooksBy authors = ...return all books by these authors...
+--
+
+-- | Lookup a potentially value-less query string parameter with boolean
+-- semantics. If the param sym is there without any value, or if
+-- it's there with value "true" or "1", it's interpreted as True.
+-- Otherwise, it's interpreted as False.
+--
+-- Example:
+--
+--
+-- -- /books?published
+-- type MyApi = "books" :> QueryFlag "published" :> Get [Book]
+--
+data QueryFlag sym
+
+-- | If you use QueryFlag "published" in one of the
+-- endpoints for your API, this automatically requires your server-side
+-- handler to be a function that takes an argument of type Bool.
+--
+-- Example:
+--
+--
+-- type MyApi = "books" :> QueryFlag "published" :> Get [Book]
+--
+-- server :: Server MyApi
+-- server = getBooks
+-- where getBooks :: Bool -> EitherT (Int, String) IO [Book]
+-- getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument...
+--
+instance (KnownSymbol sym, HasServer sublayout) => HasServer (QueryFlag sym :> sublayout)
+instance (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (QueryParams sym a :> sublayout)
+instance (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (QueryParam sym a :> sublayout)
+
+module Servant.API.ReqBody
+
+-- | Extract the request body as a value of type a.
+--
+-- Example:
+--
+--
+-- -- POST /books
+-- type MyApi = "books" :> ReqBody Book :> Post Book
+--
+data ReqBody a
+
+-- | If you use ReqBody in one of the endpoints for your API, this
+-- automatically requires your server-side handler to be a function that
+-- takes an argument of the type specified by ReqBody. This lets
+-- servant worry about extracting it from the request and turning it into
+-- a value of the type you specify.
+--
+-- All it asks is for a FromJSON instance.
+--
+-- Example:
+--
+--
+-- type MyApi = "books" :> ReqBody Book :> Post Book
+--
+-- server :: Server MyApi
+-- server = postBook
+-- where postBook :: Book -> EitherT (Int, String) IO Book
+-- postBook book = ...insert into your db...
+--
+instance (FromJSON a, HasServer sublayout) => HasServer (ReqBody a :> sublayout)
+
+module Servant.API.Get
+
+-- | Endpoint for simple GET requests. Serves the result as JSON.
+--
+-- Example:
+--
+--
+-- type MyApi = "books" :> Get [Book]
+--
+data Get a
+
+-- | When implementing the handler for a Get endpoint, just like for
+-- Delete, Post and Put, the handler code runs in
+-- the EitherT (Int, String) IO monad, where the Int
+-- represents the status code and the String a message, returned
+-- in case of failure. You can quite handily use left to quickly
+-- fail if some conditions are not met.
+--
+-- If successfully returning a value, we just require that its type has a
+-- ToJSON instance and servant takes care of encoding it for you,
+-- yielding status code 200 along the way.
+instance Typeable Get
+instance ToJSON result => HasServer (Get result)
+
+module Servant.API.Post
+
+-- | Endpoint for POST requests. The type variable represents the type of
+-- the response body (not the request body, use RQBody for that).
+--
+-- Example:
+--
+--
+-- -- POST /books
+-- -- with a JSON encoded Book as the request body
+-- -- returning the just-created Book
+-- type MyApi = "books" :> ReqBody Book :> Post Book
+--
+data Post a
+
+-- | When implementing the handler for a Post endpoint, just like
+-- for Delete, Get and Put, the handler code runs in
+-- the EitherT (Int, String) IO monad, where the Int
+-- represents the status code and the String a message, returned
+-- in case of failure. You can quite handily use left to quickly
+-- fail if some conditions are not met.
+--
+-- If successfully returning a value, we just require that its type has a
+-- ToJSON instance and servant takes care of encoding it for you,
+-- yielding status code 201 along the way.
+instance Typeable Post
+instance ToJSON a => HasServer (Post a)
+
+module Servant.API.Delete
+
+-- | Combinator for DELETE requests.
+--
+-- Example:
+--
+--
+-- -- DELETE /books/:isbn
+-- type MyApi = "books" :> Capture "isbn" Text :> Delete
+--
+data Delete
+
+-- | If you have a Delete endpoint in your API, the handler for this
+-- endpoint is meant to delete a resource.
+--
+-- The code of the handler will, just like for Get, Post
+-- and Put, run in EitherT (Int, String) IO (). The
+-- Int represents the status code and the String a message
+-- to be returned. You can use left to painlessly error out if the
+-- conditions for a successful deletion are not met.
+instance Typeable Delete
+instance HasServer Delete
+
+module Servant.API.Put
+
+-- | Endpoint for PUT requests, usually used to update a ressource. The
+-- type a is the type of the response body that's returned.
+--
+-- Example:
+--
+--
+-- -- PUT /books/:isbn
+-- -- with a Book as request body, returning the updated Book
+-- type MyApi = "books" :> Capture "isbn" Text :> ReqBody Book :> Put Book
+--
+data Put a
+
+-- | When implementing the handler for a Put endpoint, just like for
+-- Delete, Get and Post, the handler code runs in
+-- the EitherT (Int, String) IO monad, where the Int
+-- represents the status code and the String a message, returned
+-- in case of failure. You can quite handily use left to quickly
+-- fail if some conditions are not met.
+--
+-- If successfully returning a value, we just require that its type has a
+-- ToJSON instance and servant takes care of encoding it for you,
+-- yielding status code 200 along the way.
+instance Typeable Put
+instance ToJSON a => HasServer (Put a)
+
+
+-- | QuasiQuoting utilities for API types.
+--
+-- sitemap allows you to write your type in a very natural way:
+--
+--
+-- [sitemap|
+-- PUT hello String -> ()
+-- POST hello/p:Int String -> ()
+-- GET hello/?name:String Int
+-- |]
+--
+--
+-- Will generate:
+--
+--
+-- "hello" :> ReqBody String :> Put ()
+-- :<|> "hello" :> Capture "p" Int :> ReqBody String :> Post ()
+-- :<|> "hello" :> QueryParam "name" String :> Get Int
+--
+--
+-- Note the / before a QueryParam!
+module Servant.QQ
+
+-- | Finally-tagless encoding for our DSL. Keeping repr' and
+-- repr distinct when writing functions with an ExpSYM
+-- context ensures certain invariants (for instance, that there is only
+-- one of get, post, put, and delete in a
+-- value), but sometimes requires a little more work.
+class ExpSYM repr' repr | repr -> repr', repr' -> repr
+lit :: ExpSYM repr' repr => String -> repr' -> repr
+capture :: ExpSYM repr' repr => String -> String -> repr -> repr
+reqBody :: ExpSYM repr' repr => String -> repr -> repr
+queryParam :: ExpSYM repr' repr => String -> String -> repr -> repr
+conj :: ExpSYM repr' repr => repr' -> repr -> repr
+get :: ExpSYM repr' repr => String -> repr
+post :: ExpSYM repr' repr => String -> repr
+put :: ExpSYM repr' repr => String -> repr
+delete :: ExpSYM repr' repr => String -> repr
+(>:) :: Type -> Type -> Type
+parseMethod :: ExpSYM repr' repr => Parser (String -> repr)
+parseUrlSegment :: ExpSYM repr repr => Parser (repr -> repr)
+parseUrl :: ExpSYM repr repr => Parser (repr -> repr)
+data Typ
+Val :: String -> Typ
+ReqArgVal :: String -> String -> Typ
+parseTyp :: Parser Typ
+parseEntry :: ExpSYM repr repr => Parser repr
+blockComment :: Parser ()
+inlineComment :: Parser ()
+eol :: Parser String
+eols :: Parser ()
+parseAll :: Parser Type
+
+-- | The sitemap QuasiQuoter.
+--
+--
method ... typ1 -> typ2 becomes a
+-- method with request body of typ1 and returning
+-- typ2
+--
+--
+-- Comments are allowed, and have the standard Haskell format
+--
+--
+--
-- for inline
+--
{- ... -} for block
+--
+sitemap :: QuasiQuoter
+instance ExpSYM Type Type
+
+
+-- | Type safe internal links.
+--
+-- Provides the function mkLink:
+--
+--
+-- type API = Proxy ("hello" :> Get Int
+-- :| "bye" :> QueryParam "name" String :> Post Bool)
+--
+-- api :: API
+-- api = proxy
+--
+-- link1 :: Proxy ("hello" :> Get Int)
+-- link1 = proxy
+--
+-- link2 :: Proxy ("hello" :> Delete)
+-- link2 = proxy
+--
+-- mkLink link1 API -- typechecks, returns 'Link "/hello"'
+--
+-- mkLink link2 API -- doesn't typecheck
+--
+--
+-- That is, mkLink takes two arguments, a link proxy and a
+-- sitemap, and returns a Link, but only typechecks if the link
+-- proxy is a valid link, and part of the sitemap.
+--
+-- N.B.:mkLink assumes a capture matches any string
+-- (without slashes).
+module Servant.Utils.Links
+
+-- | The 'ValidLinkIn f s' constraint holds when s is an API that
+-- contains f, and f is a link.
+class ValidLinkIn f s
+mkLink :: ValidLinkIn f s => f -> s -> Link
+data Link
+Link :: String -> Link
+class VLinkHelper f
+vlh :: VLinkHelper f => proxy f -> String
+instance Show Link
+instance VLinkHelper (Post x)
+instance VLinkHelper (Get x)
+instance (KnownSymbol s, VLinkHelper e) => VLinkHelper (s :> e)
+instance (IsElem f s ~ 'True, IsLink f ~ 'True, VLinkHelper f) => ValidLinkIn f s
+
+module Servant.API.Raw
+
+-- | Endpoint for plugging in your own Wai Applications.
+--
+-- The given Application will get the request as received by the
+-- server, potentially with a modified (stripped) pathInfo if the
+-- Application is being routed with :>.
+--
+-- In addition to just letting you plug in your existing WAI
+-- Applications, this can also be used with serveDirectory
+-- to serve static files stored in a particular directory on your
+-- filesystem, or to serve your API's documentation with
+-- serveDocumentation.
+data Raw
+
+-- | Just pass the request to the underlying application and serve its
+-- response.
+--
+-- Example:
+--
+--
+-- type MyApi = "images" :> Raw
+--
+-- server :: Server MyApi
+-- server = serveDirectory "/var/www/images"
+--
+instance HasServer Raw
+
+
+-- | This module defines a sever-side handler that lets you serve static
+-- files.
+--
+--
+--
serveDirectory lets you serve anything that lives under a
+-- particular directory on your filesystem.
+--
+module Servant.Utils.StaticFiles
+
+-- | Serve anything under the specified directory as a Raw endpoint.
+--
+--
+-- type MyApi = "static" :> Raw
+--
+-- server :: Server MyApi
+-- server = serveDirectory "/var/www"
+--
+--
+-- would capture any request to /static/<something> and
+-- look for <something> under /var/www.
+--
+-- It will do its best to guess the MIME type for that file, based on the
+-- extension, and send an appropriate Content-Type header if
+-- possible.
+--
+-- If your goal is to serve HTML, CSS and Javascript files that use the
+-- rest of the API as a webapp backend, you will most likely not want the
+-- static files to be hidden behind a /static/ prefix. In that
+-- case, remember to put the serveDirectory handler in the last
+-- position, because servant will try to match the handlers in
+-- order.
+serveDirectory :: FilePath -> Server Raw
+
+module Servant.API
+
+module Servant
+
+-- | A concrete, poly-kinded proxy type
+data Proxy (t :: k) :: k -> *
+Proxy :: Proxy
diff --git a/src/Servant-API-Alternative.html b/src/Servant-API-Alternative.html
new file mode 100644
index 00000000..5a001213
--- /dev/null
+++ b/src/Servant-API-Alternative.html
@@ -0,0 +1,50 @@
+
+
+
+
+
+src/Servant/API/Alternative.hs
+
+
+
+
{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+moduleServant.API.Alternativewhere
+
+importData.Monoid
+importData.Proxy
+importServant.Server
+
+-- | Union of two APIs, first takes precedence in case of overlap.
+--
+-- Example:
+--
+-- > type MyApi = "books" :> Get [Book] -- GET /books
+-- > :<|> "books" :> ReqBody Book :> Post Book -- POST /books
+dataa:<|>b=a:<|>b
+infixr8:<|>
+
+-- | A server for @a ':<|>' b@ first tries to match the request again the route
+-- represented by @a@ and if it fails tries @b@. You must provide a request
+-- handler for each route.
+--
+-- > type MyApi = "books" :> Get [Book] -- GET /books
+-- > :<|> "books" :> ReqBody Book :> Post Book -- POST /books
+-- >
+-- > server :: Server MyApi
+-- > server = listAllBooks :<|> postBook
+-- > where listAllBooks = ...
+-- > postBook book = ...
+instance(HasServera,HasServerb)=>HasServer(a:<|>b)where
+typeServer(a:<|>b)=Servera:<|>Serverb
+routeProxy(a:<|>b)requestrespond=
+routepaarequest$\mResponse->
+ifisMismatchmResponse
+thenroutepbbrequest$\mResponse'->respond(mResponse<>mResponse')
+elserespondmResponse
+
+wherepa=Proxy::Proxya
+pb=Proxy::Proxyb
+
{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+moduleServant.API.Capture(Capture)where
+
+importData.Proxy
+importData.Text
+importGHC.TypeLits
+importNetwork.Wai
+importServant.API.Sub
+importServant.Common.Text
+importServant.Server
+
+-- | Capture a value from the request path under a certain type @a@.
+--
+-- Example:
+--
+-- > -- GET /books/:isbn
+-- > type MyApi = "books" :> Capture "isbn" Text :> Get Book
+dataCapturesyma
+
+captured::FromTexta=>proxy(Capturesyma)->Text->Maybea
+captured_=fromText
+
+-- | If you use 'Capture' in one of the endpoints for your API,
+-- this automatically requires your server-side handler to be a function
+-- that takes an argument of the type specified by the 'Capture'.
+-- This lets servant worry about getting it from the URL and turning
+-- it into a value of the type you specify.
+--
+-- You can control how it'll be converted from 'Text' to your type
+-- by simply providing an instance of 'FromText' for your type.
+--
+-- Example:
+--
+-- > type MyApi = "books" :> Capture "isbn" Text :> Get Book
+-- >
+-- > server :: Server MyApi
+-- > server = getBook
+-- > where getBook :: Text -> EitherT (Int, String) IO Book
+-- > getBook isbn = ...
+instance(KnownSymbolcapture,FromTexta,HasServersublayout)
+=>HasServer(Capturecapturea:>sublayout)where
+
+typeServer(Capturecapturea:>sublayout)=
+a->Serversublayout
+
+routeProxysubserverrequestrespond=casepathInforequestof
+(first:rest)
+->casecapturedcaptureProxyfirstof
+Nothing->respond$failWithNotFound
+Justv->route(Proxy::Proxysublayout)(subserverv)request{
+pathInfo=rest
+}respond
+_->respond$failWithNotFound
+
+wherecaptureProxy=Proxy::Proxy(Capturecapturea)
+
{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+moduleServant.API.Deletewhere
+
+importControl.Monad.Trans.Either
+importData.Proxy
+importData.String.Conversions
+importData.Typeable
+importNetwork.HTTP.Types
+importNetwork.Wai
+importServant.Server
+
+-- | Combinator for DELETE requests.
+--
+-- Example:
+--
+-- > -- DELETE /books/:isbn
+-- > type MyApi = "books" :> Capture "isbn" Text :> Delete
+dataDelete
+derivingTypeable
+
+-- | If you have a 'Delete' endpoint in your API,
+-- the handler for this endpoint is meant to delete
+-- a resource.
+--
+-- The code of the handler will, just like
+-- for 'Servant.API.Get.Get', 'Servant.API.Post.Post' and
+-- 'Servant.API.Put.Put', run in @EitherT (Int, String) IO ()@.
+-- The 'Int' represents the status code and the 'String' a message
+-- to be returned. You can use 'Control.Monad.Trans.Either.left' to
+-- painlessly error out if the conditions for a successful deletion
+-- are not met.
+instanceHasServerDeletewhere
+typeServerDelete=EitherT(Int,String)IO()
+
+routeProxyactionrequestrespond
+|null(pathInforequest)&&requestMethodrequest==methodDelete=do
+e<-runEitherTaction
+respond$succeedWith$caseeof
+Right()->
+responseLBSstatus204[]""
+Left(status,message)->
+responseLBS(mkStatusstatus(csmessage))[](csmessage)
+|null(pathInforequest)&&requestMethodrequest/=methodDelete=
+respond$failWithWrongMethod
+|otherwise=respond$failWithNotFound
+
{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+moduleServant.API.Getwhere
+
+importControl.Monad.Trans.Either
+importData.Aeson
+importData.Proxy
+importData.String.Conversions
+importData.Typeable
+importNetwork.HTTP.Types
+importNetwork.Wai
+importServant.Server
+
+-- | Endpoint for simple GET requests. Serves the result as JSON.
+--
+-- Example:
+--
+-- > type MyApi = "books" :> Get [Book]
+dataGeta
+derivingTypeable
+
+-- | When implementing the handler for a 'Get' endpoint,
+-- just like for 'Servant.API.Delete.Delete', 'Servant.API.Post.Post'
+-- and 'Servant.API.Put.Put', the handler code runs in the
+-- @EitherT (Int, String) IO@ monad, where the 'Int' represents
+-- the status code and the 'String' a message, returned in case of
+-- failure. You can quite handily use 'Control.Monad.Trans.EitherT.left'
+-- to quickly fail if some conditions are not met.
+--
+-- If successfully returning a value, we just require that its type has
+-- a 'ToJSON' instance and servant takes care of encoding it for you,
+-- yielding status code 200 along the way.
+instanceToJSONresult=>HasServer(Getresult)where
+typeServer(Getresult)=EitherT(Int,String)IOresult
+routeProxyactionrequestrespond
+|null(pathInforequest)&&requestMethodrequest==methodGet=do
+e<-runEitherTaction
+respond.succeedWith$caseeof
+Rightoutput->
+responseLBSok200[("Content-Type","application/json")](encodeoutput)
+Left(status,message)->
+responseLBS(mkStatusstatus(csmessage))[](csmessage)
+|null(pathInforequest)&&requestMethodrequest/=methodGet=
+respond$failWithWrongMethod
+|otherwise=respond$failWithNotFound
+
{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+moduleServant.API.Postwhere
+
+importControl.Monad.Trans.Either
+importData.Aeson
+importData.Proxy
+importData.String.Conversions
+importData.Typeable
+importNetwork.HTTP.Types
+importNetwork.Wai
+importServant.Server
+
+-- | Endpoint for POST requests. The type variable represents the type of the
+-- response body (not the request body, use 'Servant.API.RQBody.RQBody' for
+-- that).
+--
+-- Example:
+--
+-- > -- POST /books
+-- > -- with a JSON encoded Book as the request body
+-- > -- returning the just-created Book
+-- > type MyApi = "books" :> ReqBody Book :> Post Book
+dataPosta
+derivingTypeable
+
+-- | When implementing the handler for a 'Post' endpoint,
+-- just like for 'Servant.API.Delete.Delete', 'Servant.API.Get.Get'
+-- and 'Servant.API.Put.Put', the handler code runs in the
+-- @EitherT (Int, String) IO@ monad, where the 'Int' represents
+-- the status code and the 'String' a message, returned in case of
+-- failure. You can quite handily use 'Control.Monad.Trans.EitherT.left'
+-- to quickly fail if some conditions are not met.
+--
+-- If successfully returning a value, we just require that its type has
+-- a 'ToJSON' instance and servant takes care of encoding it for you,
+-- yielding status code 201 along the way.
+instanceToJSONa=>HasServer(Posta)where
+typeServer(Posta)=EitherT(Int,String)IOa
+
+routeProxyactionrequestrespond
+|null(pathInforequest)&&requestMethodrequest==methodPost=do
+e<-runEitherTaction
+respond.succeedWith$caseeof
+Rightout->
+responseLBSstatus201[("Content-Type","application/json")](encodeout)
+Left(status,message)->
+responseLBS(mkStatusstatus(csmessage))[](csmessage)
+|null(pathInforequest)&&requestMethodrequest/=methodPost=
+respond$failWithWrongMethod
+|otherwise=respond$failWithNotFound
+
{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+moduleServant.API.Putwhere
+
+importControl.Monad.Trans.Either
+importData.Aeson
+importData.Proxy
+importData.String.Conversions
+importData.Typeable
+importNetwork.HTTP.Types
+importNetwork.Wai
+importServant.Server
+
+-- | Endpoint for PUT requests, usually used to update a ressource.
+-- The type @a@ is the type of the response body that's returned.
+--
+-- Example:
+--
+-- > -- PUT /books/:isbn
+-- > -- with a Book as request body, returning the updated Book
+-- > type MyApi = "books" :> Capture "isbn" Text :> ReqBody Book :> Put Book
+dataPuta
+derivingTypeable
+
+-- | When implementing the handler for a 'Put' endpoint,
+-- just like for 'Servant.API.Delete.Delete', 'Servant.API.Get.Get'
+-- and 'Servant.API.Post.Post', the handler code runs in the
+-- @EitherT (Int, String) IO@ monad, where the 'Int' represents
+-- the status code and the 'String' a message, returned in case of
+-- failure. You can quite handily use 'Control.Monad.Trans.EitherT.left'
+-- to quickly fail if some conditions are not met.
+--
+-- If successfully returning a value, we just require that its type has
+-- a 'ToJSON' instance and servant takes care of encoding it for you,
+-- yielding status code 200 along the way.
+instanceToJSONa=>HasServer(Puta)where
+typeServer(Puta)=EitherT(Int,String)IOa
+
+routeProxyactionrequestrespond
+|null(pathInforequest)&&requestMethodrequest==methodPut=do
+e<-runEitherTaction
+respond.succeedWith$caseeof
+Rightout->
+responseLBSok200[("Content-Type","application/json")](encodeout)
+Left(status,message)->
+responseLBS(mkStatusstatus(csmessage))[](csmessage)
+|null(pathInforequest)&&requestMethodrequest/=methodPut=
+respond$failWithWrongMethod
+
+|otherwise=respond$failWithNotFound
+
{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+moduleServant.API.QueryParamwhere
+
+importData.Maybe
+importData.Proxy
+importData.String.Conversions
+importGHC.TypeLits
+importNetwork.HTTP.Types
+importNetwork.Wai
+importServant.API.Sub
+importServant.Common.Text
+importServant.Server
+
+-- | Lookup the value associated to the @sym@ query string parameter
+-- and try to extract it as a value of type @a@.
+--
+-- Example:
+--
+-- > -- /books?author=<author name>
+-- > type MyApi = "books" :> QueryParam "author" Text :> Get [Book]
+dataQueryParamsyma
+
+-- | If you use @'QueryParam' "author" Text@ in one of the endpoints for your API,
+-- this automatically requires your server-side handler to be a function
+-- that takes an argument of type @'Maybe' 'Text'@.
+--
+-- This lets servant worry about looking it up in the query string
+-- and turning it into a value of the type you specify, enclosed
+-- in 'Maybe', because it may not be there and servant would then
+-- hand you 'Nothing'.
+--
+-- You can control how it'll be converted from 'Text' to your type
+-- by simply providing an instance of 'FromText' for your type.
+--
+-- Example:
+--
+-- > type MyApi = "books" :> QueryParam "author" Text :> Get [Book]
+-- >
+-- > server :: Server MyApi
+-- > server = getBooksBy
+-- > where getBooksBy :: Maybe Text -> EitherT (Int, String) IO [Book]
+-- > getBooksBy Nothing = ...return all books...
+-- > getBooksBy (Just author) = ...return books by the given author...
+instance(KnownSymbolsym,FromTexta,HasServersublayout)
+=>HasServer(QueryParamsyma:>sublayout)where
+
+typeServer(QueryParamsyma:>sublayout)=
+Maybea->Serversublayout
+
+routeProxysubserverrequestrespond=do
+letquerytext=parseQueryText$rawQueryStringrequest
+param=
+caselookupparamnamequerytextof
+Nothing->Nothing-- param absent from the query string
+JustNothing->Nothing-- param present with no value -> Nothing
+Just(Justv)->fromTextv-- if present, we try to convert to
+-- the right type
+
+route(Proxy::Proxysublayout)(subserverparam)requestrespond
+
+whereparamname=cs$symbolVal(Proxy::Proxysym)
+
+-- | Lookup the values associated to the @sym@ query string parameter
+-- and try to extract it as a value of type @[a]@. This is typically
+-- meant to support query string parameters of the form
+-- @param[]=val1¶m[]=val2@ and so on. Note that servant doesn't actually
+-- require the @[]@s and will fetch the values just fine with
+-- @param=val1¶m=val2@, too.
+--
+-- Example:
+--
+-- > -- /books?authors[]=<author1>&authors[]=<author2>&...
+-- > type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]
+dataQueryParamssyma
+
+-- | If you use @'QueryParams' "authors" Text@ in one of the endpoints for your API,
+-- this automatically requires your server-side handler to be a function
+-- that takes an argument of type @['Text']@.
+--
+-- This lets servant worry about looking up 0 or more values in the query string
+-- associated to @authors@ and turning each of them into a value of
+-- the type you specify.
+--
+-- You can control how the individual values are converted from 'Text' to your type
+-- by simply providing an instance of 'FromText' for your type.
+--
+-- Example:
+--
+-- > type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]
+-- >
+-- > server :: Server MyApi
+-- > server = getBooksBy
+-- > where getBooksBy :: [Text] -> EitherT (Int, String) IO [Book]
+-- > getBooksBy authors = ...return all books by these authors...
+instance(KnownSymbolsym,FromTexta,HasServersublayout)
+=>HasServer(QueryParamssyma:>sublayout)where
+
+typeServer(QueryParamssyma:>sublayout)=
+[a]->Serversublayout
+
+routeProxysubserverrequestrespond=do
+letquerytext=parseQueryText$rawQueryStringrequest
+-- if sym is "foo", we look for query string parameters
+-- named "foo" or "foo[]" and call fromText on the
+-- corresponding values
+parameters=filterlooksLikeParamquerytext
+values=catMaybes$map(convert.snd)parameters
+
+route(Proxy::Proxysublayout)(subservervalues)requestrespond
+
+whereparamname=cs$symbolVal(Proxy::Proxysym)
+looksLikeParam(name,_)=name==paramname||name==(paramname<>"[]")
+convertNothing=Nothing
+convert(Justv)=fromTextv
+
+-- | Lookup a potentially value-less query string parameter
+-- with boolean semantics. If the param @sym@ is there without any value,
+-- or if it's there with value "true" or "1", it's interpreted as 'True'.
+-- Otherwise, it's interpreted as 'False'.
+--
+-- Example:
+--
+-- > -- /books?published
+-- > type MyApi = "books" :> QueryFlag "published" :> Get [Book]
+dataQueryFlagsym
+
+-- | If you use @'QueryFlag' "published"@ in one of the endpoints for your API,
+-- this automatically requires your server-side handler to be a function
+-- that takes an argument of type 'Bool'.
+--
+-- Example:
+--
+-- > type MyApi = "books" :> QueryFlag "published" :> Get [Book]
+-- >
+-- > server :: Server MyApi
+-- > server = getBooks
+-- > where getBooks :: Bool -> EitherT (Int, String) IO [Book]
+-- > getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument...
+instance(KnownSymbolsym,HasServersublayout)
+=>HasServer(QueryFlagsym:>sublayout)where
+
+typeServer(QueryFlagsym:>sublayout)=
+Bool->Serversublayout
+
+routeProxysubserverrequestrespond=do
+letquerytext=parseQueryText$rawQueryStringrequest
+param=caselookupparamnamequerytextof
+JustNothing->True-- param is there, with no value
+Just(Justv)->examinev-- param with a value
+Nothing->False-- param not in the query string
+
+route(Proxy::Proxysublayout)(subserverparam)requestrespond
+
+whereparamname=cs$symbolVal(Proxy::Proxysym)
+examinev|v=="true"||v=="1"||v==""=True
+|otherwise=False
+
{-# LANGUAGE InstanceSigs #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TypeFamilies #-}
+moduleServant.API.Rawwhere
+
+importData.Proxy
+importNetwork.Wai
+importServant.Server
+
+-- | Endpoint for plugging in your own Wai 'Application's.
+--
+-- The given 'Application' will get the request as received by the server, potentially with
+-- a modified (stripped) 'pathInfo' if the 'Application' is being routed with 'Servant.API.Sub.:>'.
+--
+-- In addition to just letting you plug in your existing WAI 'Application's,
+-- this can also be used with 'Servant.Utils.StaticFiles.serveDirectory' to serve
+-- static files stored in a particular directory on your filesystem, or to serve
+-- your API's documentation with 'Servant.Utils.StaticFiles.serveDocumentation'.
+dataRaw
+
+-- | Just pass the request to the underlying application and serve its response.
+--
+-- Example:
+--
+-- > type MyApi = "images" :> Raw
+-- >
+-- > server :: Server MyApi
+-- > server = serveDirectory "/var/www/images"
+instanceHasServerRawwhere
+typeServerRaw=Application
+routeProxyrawApplicationrequestrespond=
+rawApplicationrequest(respond.succeedWith)
+
{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+moduleServant.API.ReqBodywhere
+
+importControl.Applicative
+importData.Aeson
+importData.Proxy
+importNetwork.Wai
+importServant.API.Sub
+importServant.Server
+
+-- | Extract the request body as a value of type @a@.
+--
+-- Example:
+--
+-- > -- POST /books
+-- > type MyApi = "books" :> ReqBody Book :> Post Book
+dataReqBodya
+
+-- | If you use 'ReqBody' in one of the endpoints for your API,
+-- this automatically requires your server-side handler to be a function
+-- that takes an argument of the type specified by 'ReqBody'.
+-- This lets servant worry about extracting it from the request and turning
+-- it into a value of the type you specify.
+--
+-- All it asks is for a 'FromJSON' instance.
+--
+-- Example:
+--
+-- > type MyApi = "books" :> ReqBody Book :> Post Book
+-- >
+-- > server :: Server MyApi
+-- > server = postBook
+-- > where postBook :: Book -> EitherT (Int, String) IO Book
+-- > postBook book = ...insert into your db...
+instance(FromJSONa,HasServersublayout)
+=>HasServer(ReqBodya:>sublayout)where
+
+typeServer(ReqBodya:>sublayout)=
+a->Serversublayout
+
+routeProxysubserverrequestrespond=do
+mrqbody<-decode'<$>lazyRequestBodyrequest
+casemrqbodyof
+Nothing->respond$failWithInvalidBody
+Justv->route(Proxy::Proxysublayout)(subserverv)requestrespond
+
{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+moduleServant.API.Subwhere
+
+importData.Proxy
+importData.String.Conversions
+importGHC.TypeLits
+importNetwork.Wai
+importServant.Server
+
+-- | The contained API (second argument) can be found under @("/" ++ path)@
+-- (path being the first argument).
+--
+-- Example:
+--
+-- > -- GET /hello/world
+-- > -- returning a JSON encoded World value
+-- > type MyApi = "hello" :> "world" :> Get World
+data(path::k):>a=Proxypath:>a
+infixr9:>
+
+-- | Make sure the incoming request starts with @"/path"@, strip it and
+-- pass the rest of the request path to @sublayout@.
+instance(KnownSymbolpath,HasServersublayout)=>HasServer(path:>sublayout)where
+typeServer(path:>sublayout)=Serversublayout
+routeProxysubserverrequestrespond=casepathInforequestof
+(first:rest)
+|first==cs(symbolValproxyPath)
+->route(Proxy::Proxysublayout)subserverrequest{
+pathInfo=rest
+}respond
+_->respond$failWithNotFound
+
+whereproxyPath=Proxy::Proxypath
+
{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+-- | This module lets you implement 'Server's for defined APIs. You'll
+-- most likely just need 'serve'.
+moduleServant.Serverwhere
+
+importData.Monoid
+importData.Proxy
+importNetwork.HTTP.Types
+importNetwork.Wai
+
+-- * Implementing Servers
+
+-- | 'serve' allows you to implement an API and produce a wai 'Application'.
+--
+-- Example:
+--
+-- > type MyApi = "books" :> Get [Book] -- GET /books
+-- > :<|> "books" :> ReqBody Book :> Post Book -- POST /books
+-- >
+-- > server :: Server MyApi
+-- > server = listAllBooks :<|> postBook
+-- > where listAllBooks = ...
+-- > postBook book = ...
+-- >
+-- > app :: Application
+-- > app = serve myApi server
+-- >
+-- > main :: IO ()
+-- > main = Network.Wai.Handler.Warp.run 8080 app
+serve::HasServerlayout=>Proxylayout->Serverlayout->Application
+servepserver=toApplication(routepserver)
+
+toApplication::RoutingApplication->Application
+toApplicationrarequestrespond=do
+rarequest(routingRespond.routeResult)
+where
+routingRespond::EitherRouteMismatchResponse->IOResponseReceived
+routingRespond(LeftNotFound)=
+respond$responseLBSnotFound404[]"not found"
+routingRespond(LeftWrongMethod)=
+respond$responseLBSmethodNotAllowed405[]"method not allowed"
+routingRespond(LeftInvalidBody)=
+respond$responseLBSbadRequest400[]"Invalid JSON in request body"
+routingRespond(Rightresponse)=
+respondresponse
+
+-- * Route mismatch
+dataRouteMismatch=
+NotFound-- ^ the usual "not found" error
+|WrongMethod-- ^ a more informative "you just got the HTTP method wrong" error
+|InvalidBody-- ^ an even more informative "your json request body wasn't valid" error
+deriving(Eq,Show)
+
+-- |
+-- @
+-- > mempty = NotFound
+-- >
+-- > NotFound `mappend` x = x
+-- > WrongMethod `mappend` InvalidBody = InvalidBody
+-- > WrongMethod `mappend` _ = WrongMethod
+-- > InvalidBody `mappend` _ = InvalidBody
+-- @
+instanceMonoidRouteMismatchwhere
+mempty=NotFound
+
+NotFound`mappend`x=x
+WrongMethod`mappend`InvalidBody=InvalidBody
+WrongMethod`mappend`_=WrongMethod
+InvalidBody`mappend`_=InvalidBody
+
+-- | A wrapper around @'Either' 'RouteMismatch' a@.
+newtypeRouteResulta=
+RR{routeResult::EitherRouteMismatcha}
+deriving(Eq,Show)
+
+failWith::RouteMismatch->RouteResulta
+failWith=RR.Left
+
+succeedWith::a->RouteResulta
+succeedWith=RR.Right
+
+isMismatch::RouteResulta->Bool
+isMismatch(RR(Left_))=True
+isMismatch_=False
+
+-- | If we get a `Right`, it has precedence over everything else.
+--
+-- This in particular means that if we could get several 'Right's,
+-- only the first we encounter would be taken into account.
+instanceMonoid(RouteResulta)where
+mempty=RR$Leftmempty
+
+RR(Leftx)`mappend`RR(Lefty)=RR$Left(x<>y)
+RR(Left_)`mappend`RR(Righty)=RR$Righty
+r`mappend`_=r
+
+typeRoutingApplication=
+Request-- ^ the request, the field 'pathInfo' may be modified by url routing
+->(RouteResultResponse->IOResponseReceived)->IOResponseReceived
+
+classHasServerlayoutwhere
+typeServerlayout::*
+route::Proxylayout->Serverlayout->RoutingApplication
+
{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UndecidableInstances #-}
+-- | Type safe internal links.
+--
+-- Provides the function 'mkLink':
+--
+-- @
+-- type API = Proxy ("hello" :> Get Int
+-- :<|> "bye" :> QueryParam "name" String :> Post Bool)
+--
+-- api :: API
+-- api = proxy
+--
+-- link1 :: Proxy ("hello" :> Get Int)
+-- link1 = proxy
+--
+-- link2 :: Proxy ("hello" :> Delete)
+-- link2 = proxy
+--
+-- mkLink link1 API -- typechecks, returns 'Link "/hello"'
+--
+-- mkLink link2 API -- doesn't typecheck
+-- @
+--
+-- That is, 'mkLink' takes two arguments, a link proxy and a sitemap, and
+-- returns a 'Link', but only typechecks if the link proxy is a valid link,
+-- and part of the sitemap.
+--
+-- __N.B.:__ 'mkLink' assumes a capture matches any string (without slashes).
+moduleServant.Utils.Linkswhere
+
+importData.Proxy
+importGHC.TypeLits
+
+importServant.API.Capture
+importServant.API.ReqBody
+importServant.API.QueryParam
+importServant.API.Get
+importServant.API.Post
+importServant.API.Put
+importServant.API.Delete
+importServant.API.Sub
+importServant.API.Alternative
+
+
+typefamilyOrabwhere
+Or'False'False='False
+Or'Trueb='True
+Ora'True='True
+
+typefamilyAndabwhere
+And'True'True='True
+Anda'False='False
+And'Falseb='False
+
+typefamilyIsElemaswhere
+IsEleme(sa:<|>sb)=Or(IsElemesa)(IsElemesb)
+IsElem(e:>sa)(e:>sb)=IsElemsasb
+IsElem(e:>sa)(Capturexy:>sb)=IsElemsasb
+IsElemsa(ReqBodyx:>sb)=IsElemsasb
+IsElemsa(QueryParamxy:>sb)=IsElemsasb
+IsElemee='True
+IsElemea='False
+
+typefamilyIsLink''lwhere
+IsLink''(e:>Getx)=IsLink'e
+IsLink''(e:>Postx)=IsLink'e
+IsLink''(e:>Putx)=IsLink'e
+IsLink''(e:>Delete)=IsLink'e
+IsLink''a='False
+
+typefamilyIsLink'ewhere
+IsLink'(f::Symbol)='True
+
+typefamilyIsLinkewhere
+IsLink(a:>b)=Or(And(IsLink'a)(IsLink''b))
+(IsLink''(a:>b))
+
+
+-- | The 'ValidLinkIn f s' constraint holds when 's' is an API that
+-- contains 'f', and 'f' is a link.
+classValidLinkInfswhere
+mkLink::f->s->Link-- ^ This function will only typecheck if `f`
+-- is an URI within `s`
+
+instance(IsElemfs~'True
+,IsLinkf~'True
+,VLinkHelperf)=>ValidLinkInfswhere
+mkLink__=Link(vlh(Proxy::Proxyf))
+
+dataLink=LinkStringderivingShow
+
+classVLinkHelperfwhere
+vlh::forallproxy.proxyf->String
+
+instance(KnownSymbols,VLinkHelpere)=>VLinkHelper(s:>e)where
+vlh_="/"++symbolVal(Proxy::Proxys)++vlh(Proxy::Proxye)
+
+instanceVLinkHelper(Getx)where
+vlh_=""
+
+instanceVLinkHelper(Postx)where
+vlh_=""
+
+
-- | This module defines a sever-side handler that lets you serve static files.
+--
+-- - 'serveDirectory' lets you serve anything that lives under a particular
+-- directory on your filesystem.
+moduleServant.Utils.StaticFiles(
+serveDirectory,
+)where
+
+importFilesystem.Path.CurrentOS(decodeString)
+importNetwork.Wai.Application.Static
+importServant.API.Raw
+importServant.Server
+
+-- | Serve anything under the specified directory as a 'Raw' endpoint.
+--
+-- @
+-- type MyApi = "static" :> Raw
+--
+-- server :: Server MyApi
+-- server = serveDirectory "\/var\/www"
+-- @
+--
+-- would capture any request to @\/static\/\<something>@ and look for
+-- @\<something>@ under @\/var\/www@.
+--
+-- It will do its best to guess the MIME type for that file, based on the extension,
+-- and send an appropriate /Content-Type/ header if possible.
+--
+-- If your goal is to serve HTML, CSS and Javascript files that use the rest of the API
+-- as a webapp backend, you will most likely not want the static files to be hidden
+-- behind a /\/static\// prefix. In that case, remember to put the 'serveDirectory'
+-- handler in the last position, because /servant/ will try to match the handlers
+-- in order.
+serveDirectory::FilePath->ServerRaw
+serveDirectorydocumentRoot=
+staticApp(defaultFileServerSettings(decodeString(documentRoot++"/")))
+
moduleServant(
+-- | This module and its submodules can be used to define servant APIs. Note
+-- that these API definitions don't directly implement a server (or anything
+-- else).
+moduleServant.API,
+-- | For implementing servers for servant APIs.
+moduleServant.Server,
+-- | Using your types in request paths and query string parameters
+moduleServant.Common.Text,
+-- | Utilities on top of the servant core
+moduleServant.QQ,
+moduleServant.Utils.Links,
+moduleServant.Utils.StaticFiles,
+-- | Useful re-exports
+Proxy(..),
+)where
+
+importData.Proxy
+importServant.API
+importServant.Common.Text
+importServant.Server
+importServant.QQ
+importServant.Utils.Links
+importServant.Utils.StaticFiles
+