Built from 1defab0d2f
This commit is contained in:
parent
cec89c1cd0
commit
84b9ea271e
66 changed files with 3465 additions and 13 deletions
1
.ghci
1
.ghci
|
@ -1 +0,0 @@
|
||||||
:set -itest -isrc -packagehspec2
|
|
12
.travis.yml
12
.travis.yml
|
@ -1,12 +0,0 @@
|
||||||
language: haskell
|
|
||||||
|
|
||||||
notifications:
|
|
||||||
irc:
|
|
||||||
channels:
|
|
||||||
- "irc.freenode.org#servant"
|
|
||||||
template:
|
|
||||||
- "%{repository}#%{build_number} - %{commit} on %{branch} by %{author}: %{message}"
|
|
||||||
- "Build details: %{build_url} - Change view: %{compare_url}"
|
|
||||||
skip_join: true
|
|
||||||
on_success: change
|
|
||||||
on_failure: always
|
|
13
Servant-API-Alternative.html
Normal file
13
Servant-API-Alternative.html
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Alternative</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-Alternative.html");};
|
||||||
|
//]]>
|
||||||
|
</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-Alternative.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.Alternative</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> a <a href="#t::-60--124--62-">:<|></a> b = a <a href="#v::-60--124--62-">:<|></a> b</li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> a <a name="t::-60--124--62-" class="def">:<|></a> b <span class="fixity">infixr 8</span><span class="rightedge"></span> <a href="src/Servant-API-Alternative.html#%3A%3C%7C%3E" class="link">Source</a></p><div class="doc"><p>Union of two APIs, first takes precedence in case of overlap.</p><p>Example:</p><pre>type MyApi = "books" :> Get [Book] -- GET /books
|
||||||
|
:<|> "books" :> ReqBody Book :> Post Book -- POST /books</pre></div><div class="subs constructors"><p class="caption">Constructors</p><table><tr><td class="src">a <a name="v::-60--124--62-" class="def">:<|></a> b <span class="fixity">infixr 8</span><span class="rightedge"></span></td><td class="doc empty"> </td></tr></table></div><div class="subs instances"><p id="control.i::-60--124--62-" class="caption collapser" onclick="toggleSection('i::-60--124--62-')">Instances</p><div id="section.i::-60--124--62-" class="show"><table><tr><td class="src">(<a href="Servant-Server.html#t:HasServer">HasServer</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> b) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Alternative.html#t::-60--124--62-">(:<|>)</a> a b)</td><td class="doc"><p>A server for <code>a <code><a href="Servant-API-Alternative.html#t::-60--124--62-">:<|></a></code> b</code> first tries to match the request again the route
|
||||||
|
represented by <code>a</code> and if it fails tries <code>b</code>. You must provide a request
|
||||||
|
handler for each route.</p><pre>type MyApi = "books" :> Get [Book] -- GET /books
|
||||||
|
:<|> "books" :> ReqBody Book :> Post Book -- POST /books
|
||||||
|
|
||||||
|
server :: Server MyApi
|
||||||
|
server = listAllBooks :<|> postBook
|
||||||
|
where listAllBooks = ...
|
||||||
|
postBook book = ...</pre></td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Alternative.html#t::-60--124--62-">(:<|>)</a> a b) = <a href="Servant-API-Alternative.html#t::-60--124--62-">(:<|>)</a> (<a href="Servant-Server.html#t:Server">Server</a> a) (<a href="Servant-Server.html#t:Server">Server</a> b)</td><td class="doc empty"> </td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
|
15
Servant-API-Capture.html
Normal file
15
Servant-API-Capture.html
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Capture</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-Capture.html");};
|
||||||
|
//]]>
|
||||||
|
</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-Capture.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.Capture</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> <a href="#t:Capture">Capture</a> sym a</li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:Capture" class="def">Capture</a> sym a <a href="src/Servant-API-Capture.html#Capture" class="link">Source</a></p><div class="doc"><p>Capture a value from the request path under a certain type <code>a</code>.</p><p>Example:</p><pre> -- GET /books/:isbn
|
||||||
|
type MyApi = "books" :> Capture "isbn" Text :> Get Book</pre></div><div class="subs instances"><p id="control.i:Capture" class="caption collapser" onclick="toggleSection('i:Capture')">Instances</p><div id="section.i:Capture" class="show"><table><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> capture, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-Capture.html#t:Capture">Capture</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * capture a) sublayout)</td><td class="doc"><p>If you use <code><a href="Servant-API-Capture.html#t:Capture">Capture</a></code> 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 <code><a href="Servant-API-Capture.html#t:Capture">Capture</a></code>.
|
||||||
|
This lets servant worry about getting it from the URL and turning
|
||||||
|
it into a value of the type you specify.</p><p>You can control how it'll be converted from <code><a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a></code> to your type
|
||||||
|
by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>type MyApi = "books" :> Capture "isbn" Text :> Get Book
|
||||||
|
|
||||||
|
server :: Server MyApi
|
||||||
|
server = getBook
|
||||||
|
where getBook :: Text -> EitherT (Int, String) IO Book
|
||||||
|
getBook isbn = ...</pre></td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-Capture.html#t:Capture">Capture</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * capture a) sublayout) = a -> <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty"> </td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
|
13
Servant-API-Delete.html
Normal file
13
Servant-API-Delete.html
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Delete</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-Delete.html");};
|
||||||
|
//]]>
|
||||||
|
</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-Delete.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.Delete</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> <a href="#t:Delete">Delete</a></li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:Delete" class="def">Delete</a> <a href="src/Servant-API-Delete.html#Delete" class="link">Source</a></p><div class="doc"><p>Combinator for DELETE requests.</p><p>Example:</p><pre> -- DELETE /books/:isbn
|
||||||
|
type MyApi = "books" :> Capture "isbn" Text :> Delete</pre></div><div class="subs instances"><p id="control.i:Delete" class="caption collapser" onclick="toggleSection('i:Delete')">Instances</p><div id="section.i:Delete" class="show"><table><tr><td class="src"><a href="Servant-Server.html#t:HasServer">HasServer</a> <a href="Servant-API-Delete.html#t:Delete">Delete</a></td><td class="doc"><p>If you have a <code><a href="Servant-API-Delete.html#t:Delete">Delete</a></code> endpoint in your API,
|
||||||
|
the handler for this endpoint is meant to delete
|
||||||
|
a resource.</p><p>The code of the handler will, just like
|
||||||
|
for <code><a href="Servant-API-Get.html#t:Get">Get</a></code>, <code><a href="Servant-API-Post.html#t:Post">Post</a></code> and
|
||||||
|
<code><a href="Servant-API-Put.html#t:Put">Put</a></code>, run in <code>EitherT (Int, String) IO ()</code>.
|
||||||
|
The <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></code> represents the status code and the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></code> a message
|
||||||
|
to be returned. You can use <code><a href="https://hackage.haskell.org/package/either-4.3.2/docs/Control-Monad-Trans-Either.html#v:left">left</a></code> to
|
||||||
|
painlessly error out if the conditions for a successful deletion
|
||||||
|
are not met.</p></td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Typeable-Internal.html#t:Typeable">Typeable</a> * <a href="Servant-API-Delete.html#t:Delete">Delete</a></td><td class="doc empty"> </td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> <a href="Servant-API-Delete.html#t:Delete">Delete</a> = <a href="https://hackage.haskell.org/package/either-4.3.2/docs/Control-Monad-Trans-Either.html#t:EitherT">EitherT</a> (<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a>, <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a>) <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:IO">IO</a> ()</td><td class="doc empty"> </td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
|
12
Servant-API-Get.html
Normal file
12
Servant-API-Get.html
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Get</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-Get.html");};
|
||||||
|
//]]>
|
||||||
|
</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-Get.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.Get</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> <a href="#t:Get">Get</a> a</li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:Get" class="def">Get</a> a <a href="src/Servant-API-Get.html#Get" class="link">Source</a></p><div class="doc"><p>Endpoint for simple GET requests. Serves the result as JSON.</p><p>Example:</p><pre>type MyApi = "books" :> Get [Book]</pre></div><div class="subs instances"><p id="control.i:Get" class="caption collapser" onclick="toggleSection('i:Get')">Instances</p><div id="section.i:Get" class="show"><table><tr><td class="src"><a href="Servant-Utils-Links.html#t:VLinkHelper">VLinkHelper</a> * (<a href="Servant-API-Get.html#t:Get">Get</a> x)</td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a> result => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Get.html#t:Get">Get</a> result)</td><td class="doc"><p>When implementing the handler for a <code><a href="Servant-API-Get.html#t:Get">Get</a></code> endpoint,
|
||||||
|
just like for <code><a href="Servant-API-Delete.html#t:Delete">Delete</a></code>, <code><a href="Servant-API-Post.html#t:Post">Post</a></code>
|
||||||
|
and <code><a href="Servant-API-Put.html#t:Put">Put</a></code>, the handler code runs in the
|
||||||
|
<code>EitherT (Int, String) IO</code> monad, where the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></code> represents
|
||||||
|
the status code and the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></code> a message, returned in case of
|
||||||
|
failure. You can quite handily use <code><a href="Control-Monad-Trans-EitherT.html#v:left">left</a></code>
|
||||||
|
to quickly fail if some conditions are not met.</p><p>If successfully returning a value, we just require that its type has
|
||||||
|
a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a></code> instance and servant takes care of encoding it for you,
|
||||||
|
yielding status code 200 along the way.</p></td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Typeable-Internal.html#t:Typeable">Typeable</a> (* -> *) <a href="Servant-API-Get.html#t:Get">Get</a></td><td class="doc empty"> </td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Get.html#t:Get">Get</a> result) = <a href="https://hackage.haskell.org/package/either-4.3.2/docs/Control-Monad-Trans-Either.html#t:EitherT">EitherT</a> (<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a>, <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a>) <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:IO">IO</a> result</td><td class="doc empty"> </td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
|
17
Servant-API-Post.html
Normal file
17
Servant-API-Post.html
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Post</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-Post.html");};
|
||||||
|
//]]>
|
||||||
|
</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-Post.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.Post</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> <a href="#t:Post">Post</a> a</li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:Post" class="def">Post</a> a <a href="src/Servant-API-Post.html#Post" class="link">Source</a></p><div class="doc"><p>Endpoint for POST requests. The type variable represents the type of the
|
||||||
|
response body (not the request body, use <code><a href="Servant-API-RQBody.html#t:RQBody">RQBody</a></code> for
|
||||||
|
that).</p><p>Example:</p><pre> -- POST /books
|
||||||
|
-- with a JSON encoded Book as the request body
|
||||||
|
-- returning the just-created Book
|
||||||
|
type MyApi = "books" :> ReqBody Book :> Post Book</pre></div><div class="subs instances"><p id="control.i:Post" class="caption collapser" onclick="toggleSection('i:Post')">Instances</p><div id="section.i:Post" class="show"><table><tr><td class="src"><a href="Servant-Utils-Links.html#t:VLinkHelper">VLinkHelper</a> * (<a href="Servant-API-Post.html#t:Post">Post</a> x)</td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a> a => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Post.html#t:Post">Post</a> a)</td><td class="doc"><p>When implementing the handler for a <code><a href="Servant-API-Post.html#t:Post">Post</a></code> endpoint,
|
||||||
|
just like for <code><a href="Servant-API-Delete.html#t:Delete">Delete</a></code>, <code><a href="Servant-API-Get.html#t:Get">Get</a></code>
|
||||||
|
and <code><a href="Servant-API-Put.html#t:Put">Put</a></code>, the handler code runs in the
|
||||||
|
<code>EitherT (Int, String) IO</code> monad, where the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></code> represents
|
||||||
|
the status code and the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></code> a message, returned in case of
|
||||||
|
failure. You can quite handily use <code><a href="Control-Monad-Trans-EitherT.html#v:left">left</a></code>
|
||||||
|
to quickly fail if some conditions are not met.</p><p>If successfully returning a value, we just require that its type has
|
||||||
|
a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a></code> instance and servant takes care of encoding it for you,
|
||||||
|
yielding status code 201 along the way.</p></td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Typeable-Internal.html#t:Typeable">Typeable</a> (* -> *) <a href="Servant-API-Post.html#t:Post">Post</a></td><td class="doc empty"> </td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Post.html#t:Post">Post</a> a) = <a href="https://hackage.haskell.org/package/either-4.3.2/docs/Control-Monad-Trans-Either.html#t:EitherT">EitherT</a> (<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a>, <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a>) <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:IO">IO</a> a</td><td class="doc empty"> </td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
|
15
Servant-API-Put.html
Normal file
15
Servant-API-Put.html
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Put</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-Put.html");};
|
||||||
|
//]]>
|
||||||
|
</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-Put.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.Put</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> <a href="#t:Put">Put</a> a</li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:Put" class="def">Put</a> a <a href="src/Servant-API-Put.html#Put" class="link">Source</a></p><div class="doc"><p>Endpoint for PUT requests, usually used to update a ressource.
|
||||||
|
The type <code>a</code> is the type of the response body that's returned.</p><p>Example:</p><pre>-- PUT /books/:isbn
|
||||||
|
-- with a Book as request body, returning the updated Book
|
||||||
|
type MyApi = "books" :> Capture "isbn" Text :> ReqBody Book :> Put Book</pre></div><div class="subs instances"><p id="control.i:Put" class="caption collapser" onclick="toggleSection('i:Put')">Instances</p><div id="section.i:Put" class="show"><table><tr><td class="src"><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a> a => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Put.html#t:Put">Put</a> a)</td><td class="doc"><p>When implementing the handler for a <code><a href="Servant-API-Put.html#t:Put">Put</a></code> endpoint,
|
||||||
|
just like for <code><a href="Servant-API-Delete.html#t:Delete">Delete</a></code>, <code><a href="Servant-API-Get.html#t:Get">Get</a></code>
|
||||||
|
and <code><a href="Servant-API-Post.html#t:Post">Post</a></code>, the handler code runs in the
|
||||||
|
<code>EitherT (Int, String) IO</code> monad, where the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></code> represents
|
||||||
|
the status code and the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></code> a message, returned in case of
|
||||||
|
failure. You can quite handily use <code><a href="Control-Monad-Trans-EitherT.html#v:left">left</a></code>
|
||||||
|
to quickly fail if some conditions are not met.</p><p>If successfully returning a value, we just require that its type has
|
||||||
|
a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a></code> instance and servant takes care of encoding it for you,
|
||||||
|
yielding status code 200 along the way.</p></td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Typeable-Internal.html#t:Typeable">Typeable</a> (* -> *) <a href="Servant-API-Put.html#t:Put">Put</a></td><td class="doc empty"> </td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Put.html#t:Put">Put</a> a) = <a href="https://hackage.haskell.org/package/either-4.3.2/docs/Control-Monad-Trans-Either.html#t:EitherT">EitherT</a> (<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a>, <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a>) <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:IO">IO</a> a</td><td class="doc empty"> </td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
|
45
Servant-API-QueryParam.html
Normal file
45
Servant-API-QueryParam.html
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.QueryParam</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-QueryParam.html");};
|
||||||
|
//]]>
|
||||||
|
</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-QueryParam.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.QueryParam</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> <a href="#t:QueryParam">QueryParam</a> sym a</li><li class="src short"><span class="keyword">data</span> <a href="#t:QueryParams">QueryParams</a> sym a</li><li class="src short"><span class="keyword">data</span> <a href="#t:QueryFlag">QueryFlag</a> sym</li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:QueryParam" class="def">QueryParam</a> sym a <a href="src/Servant-API-QueryParam.html#QueryParam" class="link">Source</a></p><div class="doc"><p>Lookup the value associated to the <code>sym</code> query string parameter
|
||||||
|
and try to extract it as a value of type <code>a</code>.</p><p>Example:</p><pre>-- /books?author=<author name>
|
||||||
|
type MyApi = "books" :> QueryParam "author" Text :> Get [Book]</pre></div><div class="subs instances"><p id="control.i:QueryParam" class="caption collapser" onclick="toggleSection('i:QueryParam')">Instances</p><div id="section.i:QueryParam" class="show"><table><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a></code> "author" Text</code> 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 <code><code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a></code> <code>Text</code></code>.</p><p>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 <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a></code>, because it may not be there and servant would then
|
||||||
|
hand you <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#v:Nothing">Nothing</a></code>.</p><p>You can control how it'll be converted from <code>Text</code> to your type
|
||||||
|
by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>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...</pre></td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout) = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a> a -> <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty"> </td></tr></table></div></div></div><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:QueryParams" class="def">QueryParams</a> sym a <a href="src/Servant-API-QueryParam.html#QueryParams" class="link">Source</a></p><div class="doc"><p>Lookup the values associated to the <code>sym</code> query string parameter
|
||||||
|
and try to extract it as a value of type <code>[a]</code>. This is typically
|
||||||
|
meant to support query string parameters of the form
|
||||||
|
<code>param[]=val1&param[]=val2</code> and so on. Note that servant doesn't actually
|
||||||
|
require the <code>[]</code>s and will fetch the values just fine with
|
||||||
|
<code>param=val1&param=val2</code>, too.</p><p>Example:</p><pre>-- /books?authors[]=<author1>&authors[]=<author2>&...
|
||||||
|
type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]</pre></div><div class="subs instances"><p id="control.i:QueryParams" class="caption collapser" onclick="toggleSection('i:QueryParams')">Instances</p><div id="section.i:QueryParams" class="show"><table><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParams">QueryParams</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryParams">QueryParams</a></code> "authors" Text</code> 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 <code>[<code>Text</code>]</code>.</p><p>This lets servant worry about looking up 0 or more values in the query string
|
||||||
|
associated to <code>authors</code> and turning each of them into a value of
|
||||||
|
the type you specify.</p><p>You can control how the individual values are converted from <code>Text</code> to your type
|
||||||
|
by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>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...</pre></td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParams">QueryParams</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout) = [a] -> <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty"> </td></tr></table></div></div></div><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:QueryFlag" class="def">QueryFlag</a> sym <a href="src/Servant-API-QueryParam.html#QueryFlag" class="link">Source</a></p><div class="doc"><p>Lookup a potentially value-less query string parameter
|
||||||
|
with boolean semantics. If the param <code>sym</code> is there without any value,
|
||||||
|
or if it's there with value "true" or "1", it's interpreted as <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:True">True</a></code>.
|
||||||
|
Otherwise, it's interpreted as <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:False">False</a></code>.</p><p>Example:</p><pre>-- /books?published
|
||||||
|
type MyApi = "books" :> QueryFlag "published" :> Get [Book]</pre></div><div class="subs instances"><p id="control.i:QueryFlag" class="caption collapser" onclick="toggleSection('i:QueryFlag')">Instances</p><div id="section.i:QueryFlag" class="show"><table><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-QueryParam.html#t:QueryFlag">QueryFlag</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> sym) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryFlag">QueryFlag</a></code> "published"</code> 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 <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a></code>.</p><p>Example:</p><pre>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...</pre></td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-QueryParam.html#t:QueryFlag">QueryFlag</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> sym) sublayout) = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a> -> <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty"> </td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
|
11
Servant-API-Raw.html
Normal file
11
Servant-API-Raw.html
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Raw</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-Raw.html");};
|
||||||
|
//]]>
|
||||||
|
</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-Raw.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.Raw</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> <a href="#t:Raw">Raw</a></li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:Raw" class="def">Raw</a> <a href="src/Servant-API-Raw.html#Raw" class="link">Source</a></p><div class="doc"><p>Endpoint for plugging in your own Wai <code><a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></code>s.</p><p>The given <code><a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></code> will get the request as received by the server, potentially with
|
||||||
|
a modified (stripped) <code><a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#v:pathInfo">pathInfo</a></code> if the <code><a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></code> is being routed with <code><a href="Servant-API-Sub.html#t::-62-">:></a></code>.</p><p>In addition to just letting you plug in your existing WAI <code><a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></code>s,
|
||||||
|
this can also be used with <code><a href="Servant-Utils-StaticFiles.html#v:serveDirectory">serveDirectory</a></code> to serve
|
||||||
|
static files stored in a particular directory on your filesystem, or to serve
|
||||||
|
your API's documentation with <code><a href="Servant-Utils-StaticFiles.html#v:serveDocumentation">serveDocumentation</a></code>.</p></div><div class="subs instances"><p id="control.i:Raw" class="caption collapser" onclick="toggleSection('i:Raw')">Instances</p><div id="section.i:Raw" class="show"><table><tr><td class="src"><a href="Servant-Server.html#t:HasServer">HasServer</a> <a href="Servant-API-Raw.html#t:Raw">Raw</a></td><td class="doc"><p>Just pass the request to the underlying application and serve its response.</p><p>Example:</p><pre>type MyApi = "images" :> Raw
|
||||||
|
|
||||||
|
server :: Server MyApi
|
||||||
|
server = serveDirectory "/var/www/images"</pre></td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> <a href="Servant-API-Raw.html#t:Raw">Raw</a> = <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></td><td class="doc empty"> </td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
|
14
Servant-API-ReqBody.html
Normal file
14
Servant-API-ReqBody.html
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.ReqBody</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-ReqBody.html");};
|
||||||
|
//]]>
|
||||||
|
</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-ReqBody.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.ReqBody</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> <a href="#t:ReqBody">ReqBody</a> a</li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:ReqBody" class="def">ReqBody</a> a <a href="src/Servant-API-ReqBody.html#ReqBody" class="link">Source</a></p><div class="doc"><p>Extract the request body as a value of type <code>a</code>.</p><p>Example:</p><pre> -- POST /books
|
||||||
|
type MyApi = "books" :> ReqBody Book :> Post Book</pre></div><div class="subs instances"><p id="control.i:ReqBody" class="caption collapser" onclick="toggleSection('i:ReqBody')">Instances</p><div id="section.i:ReqBody" class="show"><table><tr><td class="src">(<a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:FromJSON">FromJSON</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a> * a) sublayout)</td><td class="doc"><p>If you use <code><a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a></code> 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 <code><a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a></code>.
|
||||||
|
This lets servant worry about extracting it from the request and turning
|
||||||
|
it into a value of the type you specify.</p><p>All it asks is for a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:FromJSON">FromJSON</a></code> instance.</p><p>Example:</p><pre>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...</pre></td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a> * a) sublayout) = a -> <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty"> </td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
|
56
Servant-API-Sub.html
Normal file
56
Servant-API-Sub.html
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Sub</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-Sub.html");};
|
||||||
|
//]]>
|
||||||
|
</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-Sub.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.Sub</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> path <a href="#t::-62-">:></a> a = (<a href="Servant.html#t:Proxy">Proxy</a> path) <a href="#v::-62-">:></a> a</li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> path <a name="t::-62-" class="def">:></a> a <span class="fixity">infixr 9</span><span class="rightedge"></span> <a href="src/Servant-API-Sub.html#%3A%3E" class="link">Source</a></p><div class="doc"><p>The contained API (second argument) can be found under <code>("/" ++ path)</code>
|
||||||
|
(path being the first argument).</p><p>Example:</p><pre>-- GET /hello/world
|
||||||
|
-- returning a JSON encoded World value
|
||||||
|
type MyApi = "hello" :> "world" :> Get World</pre></div><div class="subs constructors"><p class="caption">Constructors</p><table><tr><td class="src">(<a href="Servant.html#t:Proxy">Proxy</a> path) <a name="v::-62-" class="def">:></a> a <span class="fixity">infixr 9</span><span class="rightedge"></span></td><td class="doc empty"> </td></tr></table></div><div class="subs instances"><p id="control.i::-62-" class="caption collapser" onclick="toggleSection('i::-62-')">Instances</p><div id="section.i::-62-" class="show"><table><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> s, <a href="Servant-Utils-Links.html#t:VLinkHelper">VLinkHelper</a> * e) => <a href="Servant-Utils-Links.html#t:VLinkHelper">VLinkHelper</a> * (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> s e)</td><td class="doc empty"> </td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> capture, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-Capture.html#t:Capture">Capture</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * capture a) sublayout)</td><td class="doc"><p>If you use <code><a href="Servant-API-Capture.html#t:Capture">Capture</a></code> 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 <code><a href="Servant-API-Capture.html#t:Capture">Capture</a></code>.
|
||||||
|
This lets servant worry about getting it from the URL and turning
|
||||||
|
it into a value of the type you specify.</p><p>You can control how it'll be converted from <code><a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a></code> to your type
|
||||||
|
by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>type MyApi = "books" :> Capture "isbn" Text :> Get Book
|
||||||
|
|
||||||
|
server :: Server MyApi
|
||||||
|
server = getBook
|
||||||
|
where getBook :: Text -> EitherT (Int, String) IO Book
|
||||||
|
getBook isbn = ...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-QueryParam.html#t:QueryFlag">QueryFlag</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> sym) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryFlag">QueryFlag</a></code> "published"</code> 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 <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a></code>.</p><p>Example:</p><pre>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...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParams">QueryParams</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryParams">QueryParams</a></code> "authors" Text</code> 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 <code>[<code>Text</code>]</code>.</p><p>This lets servant worry about looking up 0 or more values in the query string
|
||||||
|
associated to <code>authors</code> and turning each of them into a value of
|
||||||
|
the type you specify.</p><p>You can control how the individual values are converted from <code>Text</code> to your type
|
||||||
|
by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>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...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a></code> "author" Text</code> 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 <code><code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a></code> <code>Text</code></code>.</p><p>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 <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a></code>, because it may not be there and servant would then
|
||||||
|
hand you <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#v:Nothing">Nothing</a></code>.</p><p>You can control how it'll be converted from <code>Text</code> to your type
|
||||||
|
by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>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...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:FromJSON">FromJSON</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a> * a) sublayout)</td><td class="doc"><p>If you use <code><a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a></code> 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 <code><a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a></code>.
|
||||||
|
This lets servant worry about extracting it from the request and turning
|
||||||
|
it into a value of the type you specify.</p><p>All it asks is for a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:FromJSON">FromJSON</a></code> instance.</p><p>Example:</p><pre>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...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> path, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> path sublayout)</td><td class="doc"><p>Make sure the incoming request starts with <code>"/path"</code>, strip it and
|
||||||
|
pass the rest of the request path to <code>sublayout</code>.</p></td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-Capture.html#t:Capture">Capture</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * capture a) sublayout) = a -> <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty"> </td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-QueryParam.html#t:QueryFlag">QueryFlag</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> sym) sublayout) = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a> -> <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty"> </td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParams">QueryParams</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout) = [a] -> <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty"> </td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout) = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a> a -> <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty"> </td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a> * a) sublayout) = a -> <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty"> </td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> path sublayout) = <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty"> </td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
|
4
Servant-API.html
Normal file
4
Servant-API.html
Normal file
File diff suppressed because one or more lines are too long
7
Servant-Common-Text.html
Normal file
7
Servant-Common-Text.html
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.Common.Text</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();setSynopsis("mini_Servant-Common-Text.html");};
|
||||||
|
//]]>
|
||||||
|
</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-Common-Text.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>Safe-Inferred</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.Common.Text</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">class</span> <a href="#t:FromText">FromText</a> a <span class="keyword">where</span><ul class="subs"><li><a href="#v:fromText">fromText</a> :: <a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a> -> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a> a</li></ul></li><li class="src short"><span class="keyword">class</span> <a href="#t:ToText">ToText</a> a <span class="keyword">where</span><ul class="subs"><li><a href="#v:toText">toText</a> :: a -> <a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a></li></ul></li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">class</span> <a name="t:FromText" class="def">FromText</a> a <span class="keyword">where</span> <a href="src/Servant-Common-Text.html#FromText" class="link">Source</a></p><div class="doc"><p>For getting values from url captures and query string parameters</p></div><div class="subs methods"><p class="caption">Methods</p><p class="src"><a name="v:fromText" class="def">fromText</a> :: <a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a> -> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a> a <a href="src/Servant-Common-Text.html#fromText" class="link">Source</a></p></div><div class="subs instances"><p id="control.i:FromText" class="caption collapser" onclick="toggleSection('i:FromText')">Instances</p><div id="section.i:FromText" class="show"><table><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a></td><td class="doc"><pre>fromText "true" = Just True
|
||||||
|
fromText "false" = Just False
|
||||||
|
fromText _ = Nothing</pre></td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Double">Double</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Float">Float</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int8">Int8</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int16">Int16</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int32">Int32</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int64">Int64</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Integer">Integer</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word">Word</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word8">Word8</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word16">Word16</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word32">Word32</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word64">Word64</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a></td><td class="doc empty"> </td></tr></table></div></div></div><div class="top"><p class="src"><span class="keyword">class</span> <a name="t:ToText" class="def">ToText</a> a <span class="keyword">where</span> <a href="src/Servant-Common-Text.html#ToText" class="link">Source</a></p><div class="doc"><p>For putting values in paths and query string parameters</p></div><div class="subs methods"><p class="caption">Methods</p><p class="src"><a name="v:toText" class="def">toText</a> :: a -> <a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a> <a href="src/Servant-Common-Text.html#toText" class="link">Source</a></p></div><div class="subs instances"><p id="control.i:ToText" class="caption collapser" onclick="toggleSection('i:ToText')">Instances</p><div id="section.i:ToText" class="show"><table><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a></td><td class="doc"><pre>toText True = "true"
|
||||||
|
toText False = "false"</pre></td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Double">Double</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Float">Float</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int8">Int8</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int16">Int16</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int32">Int32</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int64">Int64</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Integer">Integer</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word">Word</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word8">Word8</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word16">Word16</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word32">Word32</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word64">Word64</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a></td><td class="doc empty"> </td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
|
17
Servant-QQ.html
Normal file
17
Servant-QQ.html
Normal file
File diff suppressed because one or more lines are too long
116
Servant-Server.html
Normal file
116
Servant-Server.html
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.Server</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();setSynopsis("mini_Servant-Server.html");};
|
||||||
|
//]]>
|
||||||
|
</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-Server.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.Server</p></div><div id="table-of-contents"><p class="caption">Contents</p><ul><li><a href="#g:1">Implementing Servers</a></li><li><a href="#g:2">Route mismatch</a></li></ul></div><div id="description"><p class="caption">Description</p><div class="doc"><p>This module lets you implement <code><a href="Servant-Server.html#t:Server">Server</a></code>s for defined APIs. You'll
|
||||||
|
most likely just need <code><a href="Servant-Server.html#v:serve">serve</a></code>.</p></div></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><a href="#v:serve">serve</a> :: <a href="Servant-Server.html#t:HasServer">HasServer</a> layout => <a href="Servant.html#t:Proxy">Proxy</a> layout -> <a href="Servant-Server.html#t:Server">Server</a> layout -> <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></li><li class="src short"><a href="#v:toApplication">toApplication</a> :: <a href="Servant-Server.html#t:RoutingApplication">RoutingApplication</a> -> <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></li><li class="src short"><span class="keyword">data</span> <a href="#t:RouteMismatch">RouteMismatch</a><ul class="subs"><li>= <a href="#v:NotFound">NotFound</a></li><li>| <a href="#v:WrongMethod">WrongMethod</a></li><li>| <a href="#v:InvalidBody">InvalidBody</a></li></ul></li><li class="src short"><span class="keyword">newtype</span> <a href="#t:RouteResult">RouteResult</a> a = <a href="#v:RR">RR</a> {<ul class="subs"><li><a href="#v:routeResult">routeResult</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Either.html#t:Either">Either</a> <a href="Servant-Server.html#t:RouteMismatch">RouteMismatch</a> a</li></ul>}</li><li class="src short"><a href="#v:failWith">failWith</a> :: <a href="Servant-Server.html#t:RouteMismatch">RouteMismatch</a> -> <a href="Servant-Server.html#t:RouteResult">RouteResult</a> a</li><li class="src short"><a href="#v:succeedWith">succeedWith</a> :: a -> <a href="Servant-Server.html#t:RouteResult">RouteResult</a> a</li><li class="src short"><a href="#v:isMismatch">isMismatch</a> :: <a href="Servant-Server.html#t:RouteResult">RouteResult</a> a -> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a></li><li class="src short"><span class="keyword">type</span> <a href="#t:RoutingApplication">RoutingApplication</a> = <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Request">Request</a> -> (<a href="Servant-Server.html#t:RouteResult">RouteResult</a> <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Response">Response</a> -> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:IO">IO</a> <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:ResponseReceived">ResponseReceived</a>) -> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:IO">IO</a> <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:ResponseReceived">ResponseReceived</a></li><li class="src short"><span class="keyword">class</span> <a href="#t:HasServer">HasServer</a> layout <span class="keyword">where</span><ul class="subs"><li><span class="keyword">type</span> <a href="#t:Server">Server</a> layout :: *</li><li><a href="#v:route">route</a> :: <a href="Servant.html#t:Proxy">Proxy</a> layout -> <a href="Servant-Server.html#t:Server">Server</a> layout -> <a href="Servant-Server.html#t:RoutingApplication">RoutingApplication</a></li></ul></li></ul></div><div id="interface"><h1 id="g:1">Implementing Servers</h1><div class="top"><p class="src"><a name="v:serve" class="def">serve</a> :: <a href="Servant-Server.html#t:HasServer">HasServer</a> layout => <a href="Servant.html#t:Proxy">Proxy</a> layout -> <a href="Servant-Server.html#t:Server">Server</a> layout -> <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a> <a href="src/Servant-Server.html#serve" class="link">Source</a></p><div class="doc"><p><code><a href="Servant-Server.html#v:serve">serve</a></code> allows you to implement an API and produce a wai <code><a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></code>.</p><p>Example:</p><pre>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</pre></div></div><div class="top"><p class="src"><a name="v:toApplication" class="def">toApplication</a> :: <a href="Servant-Server.html#t:RoutingApplication">RoutingApplication</a> -> <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a> <a href="src/Servant-Server.html#toApplication" class="link">Source</a></p></div><h1 id="g:2">Route mismatch</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:RouteMismatch" class="def">RouteMismatch</a> <a href="src/Servant-Server.html#RouteMismatch" class="link">Source</a></p><div class="subs constructors"><p class="caption">Constructors</p><table><tr><td class="src"><a name="v:NotFound" class="def">NotFound</a></td><td class="doc"><p>the usual "not found" error</p></td></tr><tr><td class="src"><a name="v:WrongMethod" class="def">WrongMethod</a></td><td class="doc"><p>a more informative "you just got the HTTP method wrong" error</p></td></tr><tr><td class="src"><a name="v:InvalidBody" class="def">InvalidBody</a></td><td class="doc"><p>an even more informative "your json request body wasn't valid" error</p></td></tr></table></div><div class="subs instances"><p id="control.i:RouteMismatch" class="caption collapser" onclick="toggleSection('i:RouteMismatch')">Instances</p><div id="section.i:RouteMismatch" class="show"><table><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Eq.html#t:Eq">Eq</a> <a href="Servant-Server.html#t:RouteMismatch">RouteMismatch</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Text-Show.html#t:Show">Show</a> <a href="Servant-Server.html#t:RouteMismatch">RouteMismatch</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Monoid.html#t:Monoid">Monoid</a> <a href="Servant-Server.html#t:RouteMismatch">RouteMismatch</a></td><td class="doc"><pre>> mempty = NotFound
|
||||||
|
>
|
||||||
|
> NotFound <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Monoid.html#v:mappend">mappend</a></code> x = x
|
||||||
|
> WrongMethod <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Monoid.html#v:mappend">mappend</a></code> InvalidBody = InvalidBody
|
||||||
|
> WrongMethod <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Monoid.html#v:mappend">mappend</a></code> _ = WrongMethod
|
||||||
|
> InvalidBody <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Monoid.html#v:mappend">mappend</a></code> _ = InvalidBody
|
||||||
|
</pre></td></tr></table></div></div></div><div class="top"><p class="src"><span class="keyword">newtype</span> <a name="t:RouteResult" class="def">RouteResult</a> a <a href="src/Servant-Server.html#RouteResult" class="link">Source</a></p><div class="doc"><p>A wrapper around <code><code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Either.html#t:Either">Either</a></code> <code><a href="Servant-Server.html#t:RouteMismatch">RouteMismatch</a></code> a</code>.</p></div><div class="subs constructors"><p class="caption">Constructors</p><table><tr><td class="src"><a name="v:RR" class="def">RR</a></td><td class="doc empty"> </td></tr><tr><td colspan="2"><div class="subs fields"><p class="caption">Fields</p><dl><dt class="src"><a name="v:routeResult" class="def">routeResult</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Either.html#t:Either">Either</a> <a href="Servant-Server.html#t:RouteMismatch">RouteMismatch</a> a</dt><dd class="doc empty"> </dd></dl><div class="clear"></div></div></td></tr></table></div><div class="subs instances"><p id="control.i:RouteResult" class="caption collapser" onclick="toggleSection('i:RouteResult')">Instances</p><div id="section.i:RouteResult" class="show"><table><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Eq.html#t:Eq">Eq</a> a => <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Eq.html#t:Eq">Eq</a> (<a href="Servant-Server.html#t:RouteResult">RouteResult</a> a)</td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Text-Show.html#t:Show">Show</a> a => <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Text-Show.html#t:Show">Show</a> (<a href="Servant-Server.html#t:RouteResult">RouteResult</a> a)</td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Monoid.html#t:Monoid">Monoid</a> (<a href="Servant-Server.html#t:RouteResult">RouteResult</a> a)</td><td class="doc"><p>If we get a <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Either.html#v:Right">Right</a></code>, it has precedence over everything else.</p><p>This in particular means that if we could get several <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Either.html#v:Right">Right</a></code>s,
|
||||||
|
only the first we encounter would be taken into account.</p></td></tr></table></div></div></div><div class="top"><p class="src"><a name="v:failWith" class="def">failWith</a> :: <a href="Servant-Server.html#t:RouteMismatch">RouteMismatch</a> -> <a href="Servant-Server.html#t:RouteResult">RouteResult</a> a <a href="src/Servant-Server.html#failWith" class="link">Source</a></p></div><div class="top"><p class="src"><a name="v:succeedWith" class="def">succeedWith</a> :: a -> <a href="Servant-Server.html#t:RouteResult">RouteResult</a> a <a href="src/Servant-Server.html#succeedWith" class="link">Source</a></p></div><div class="top"><p class="src"><a name="v:isMismatch" class="def">isMismatch</a> :: <a href="Servant-Server.html#t:RouteResult">RouteResult</a> a -> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a> <a href="src/Servant-Server.html#isMismatch" class="link">Source</a></p></div><div class="top"><p class="src"><span class="keyword">type</span> <a name="t:RoutingApplication" class="def">RoutingApplication</a> <a href="src/Servant-Server.html#RoutingApplication" class="link">Source</a></p><div class="subs arguments"><p class="caption">Arguments</p><table><tr><td class="src"> = <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Request">Request</a></td><td class="doc"><p>the request, the field <code><a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#v:pathInfo">pathInfo</a></code> may be modified by url routing</p></td></tr><tr><td class="src">-> (<a href="Servant-Server.html#t:RouteResult">RouteResult</a> <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Response">Response</a> -> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:IO">IO</a> <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:ResponseReceived">ResponseReceived</a>)</td><td class="doc empty"> </td></tr><tr><td class="src">-> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:IO">IO</a> <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:ResponseReceived">ResponseReceived</a></td><td class="doc empty"> </td></tr></table></div></div><div class="top"><p class="src"><span class="keyword">class</span> <a name="t:HasServer" class="def">HasServer</a> layout <span class="keyword">where</span> <a href="src/Servant-Server.html#HasServer" class="link">Source</a></p><div class="subs associated-types"><p class="caption">Associated Types</p><p class="src"><span class="keyword">type</span> <a name="t:Server" class="def">Server</a> layout :: * <a href="src/Servant-Server.html#Server" class="link">Source</a></p></div><div class="subs methods"><p class="caption">Methods</p><p class="src"><a name="v:route" class="def">route</a> :: <a href="Servant.html#t:Proxy">Proxy</a> layout -> <a href="Servant-Server.html#t:Server">Server</a> layout -> <a href="Servant-Server.html#t:RoutingApplication">RoutingApplication</a> <a href="src/Servant-Server.html#route" class="link">Source</a></p></div><div class="subs instances"><p id="control.i:HasServer" class="caption collapser" onclick="toggleSection('i:HasServer')">Instances</p><div id="section.i:HasServer" class="show"><table><tr><td class="src"><a href="Servant-Server.html#t:HasServer">HasServer</a> <a href="Servant-API-Delete.html#t:Delete">Delete</a></td><td class="doc"><p>If you have a <code><a href="Servant-API-Delete.html#t:Delete">Delete</a></code> endpoint in your API,
|
||||||
|
the handler for this endpoint is meant to delete
|
||||||
|
a resource.</p><p>The code of the handler will, just like
|
||||||
|
for <code><a href="Servant-API-Get.html#t:Get">Get</a></code>, <code><a href="Servant-API-Post.html#t:Post">Post</a></code> and
|
||||||
|
<code><a href="Servant-API-Put.html#t:Put">Put</a></code>, run in <code>EitherT (Int, String) IO ()</code>.
|
||||||
|
The <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></code> represents the status code and the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></code> a message
|
||||||
|
to be returned. You can use <code><a href="https://hackage.haskell.org/package/either-4.3.2/docs/Control-Monad-Trans-Either.html#v:left">left</a></code> to
|
||||||
|
painlessly error out if the conditions for a successful deletion
|
||||||
|
are not met.</p></td></tr><tr><td class="src"><a href="Servant-Server.html#t:HasServer">HasServer</a> <a href="Servant-API-Raw.html#t:Raw">Raw</a></td><td class="doc"><p>Just pass the request to the underlying application and serve its response.</p><p>Example:</p><pre>type MyApi = "images" :> Raw
|
||||||
|
|
||||||
|
server :: Server MyApi
|
||||||
|
server = serveDirectory "/var/www/images"</pre></td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a> result => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Get.html#t:Get">Get</a> result)</td><td class="doc"><p>When implementing the handler for a <code><a href="Servant-API-Get.html#t:Get">Get</a></code> endpoint,
|
||||||
|
just like for <code><a href="Servant-API-Delete.html#t:Delete">Delete</a></code>, <code><a href="Servant-API-Post.html#t:Post">Post</a></code>
|
||||||
|
and <code><a href="Servant-API-Put.html#t:Put">Put</a></code>, the handler code runs in the
|
||||||
|
<code>EitherT (Int, String) IO</code> monad, where the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></code> represents
|
||||||
|
the status code and the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></code> a message, returned in case of
|
||||||
|
failure. You can quite handily use <code><a href="Control-Monad-Trans-EitherT.html#v:left">left</a></code>
|
||||||
|
to quickly fail if some conditions are not met.</p><p>If successfully returning a value, we just require that its type has
|
||||||
|
a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a></code> instance and servant takes care of encoding it for you,
|
||||||
|
yielding status code 200 along the way.</p></td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a> a => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Post.html#t:Post">Post</a> a)</td><td class="doc"><p>When implementing the handler for a <code><a href="Servant-API-Post.html#t:Post">Post</a></code> endpoint,
|
||||||
|
just like for <code><a href="Servant-API-Delete.html#t:Delete">Delete</a></code>, <code><a href="Servant-API-Get.html#t:Get">Get</a></code>
|
||||||
|
and <code><a href="Servant-API-Put.html#t:Put">Put</a></code>, the handler code runs in the
|
||||||
|
<code>EitherT (Int, String) IO</code> monad, where the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></code> represents
|
||||||
|
the status code and the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></code> a message, returned in case of
|
||||||
|
failure. You can quite handily use <code><a href="Control-Monad-Trans-EitherT.html#v:left">left</a></code>
|
||||||
|
to quickly fail if some conditions are not met.</p><p>If successfully returning a value, we just require that its type has
|
||||||
|
a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a></code> instance and servant takes care of encoding it for you,
|
||||||
|
yielding status code 201 along the way.</p></td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a> a => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Put.html#t:Put">Put</a> a)</td><td class="doc"><p>When implementing the handler for a <code><a href="Servant-API-Put.html#t:Put">Put</a></code> endpoint,
|
||||||
|
just like for <code><a href="Servant-API-Delete.html#t:Delete">Delete</a></code>, <code><a href="Servant-API-Get.html#t:Get">Get</a></code>
|
||||||
|
and <code><a href="Servant-API-Post.html#t:Post">Post</a></code>, the handler code runs in the
|
||||||
|
<code>EitherT (Int, String) IO</code> monad, where the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></code> represents
|
||||||
|
the status code and the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></code> a message, returned in case of
|
||||||
|
failure. You can quite handily use <code><a href="Control-Monad-Trans-EitherT.html#v:left">left</a></code>
|
||||||
|
to quickly fail if some conditions are not met.</p><p>If successfully returning a value, we just require that its type has
|
||||||
|
a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a></code> instance and servant takes care of encoding it for you,
|
||||||
|
yielding status code 200 along the way.</p></td></tr><tr><td class="src">(<a href="Servant-Server.html#t:HasServer">HasServer</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> b) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Alternative.html#t::-60--124--62-">(:<|>)</a> a b)</td><td class="doc"><p>A server for <code>a <code><a href="Servant-API-Alternative.html#t::-60--124--62-">:<|></a></code> b</code> first tries to match the request again the route
|
||||||
|
represented by <code>a</code> and if it fails tries <code>b</code>. You must provide a request
|
||||||
|
handler for each route.</p><pre>type MyApi = "books" :> Get [Book] -- GET /books
|
||||||
|
:<|> "books" :> ReqBody Book :> Post Book -- POST /books
|
||||||
|
|
||||||
|
server :: Server MyApi
|
||||||
|
server = listAllBooks :<|> postBook
|
||||||
|
where listAllBooks = ...
|
||||||
|
postBook book = ...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> capture, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-Capture.html#t:Capture">Capture</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * capture a) sublayout)</td><td class="doc"><p>If you use <code><a href="Servant-API-Capture.html#t:Capture">Capture</a></code> 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 <code><a href="Servant-API-Capture.html#t:Capture">Capture</a></code>.
|
||||||
|
This lets servant worry about getting it from the URL and turning
|
||||||
|
it into a value of the type you specify.</p><p>You can control how it'll be converted from <code><a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a></code> to your type
|
||||||
|
by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>type MyApi = "books" :> Capture "isbn" Text :> Get Book
|
||||||
|
|
||||||
|
server :: Server MyApi
|
||||||
|
server = getBook
|
||||||
|
where getBook :: Text -> EitherT (Int, String) IO Book
|
||||||
|
getBook isbn = ...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-QueryParam.html#t:QueryFlag">QueryFlag</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> sym) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryFlag">QueryFlag</a></code> "published"</code> 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 <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a></code>.</p><p>Example:</p><pre>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...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParams">QueryParams</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryParams">QueryParams</a></code> "authors" Text</code> 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 <code>[<code>Text</code>]</code>.</p><p>This lets servant worry about looking up 0 or more values in the query string
|
||||||
|
associated to <code>authors</code> and turning each of them into a value of
|
||||||
|
the type you specify.</p><p>You can control how the individual values are converted from <code>Text</code> to your type
|
||||||
|
by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>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...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a></code> "author" Text</code> 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 <code><code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a></code> <code>Text</code></code>.</p><p>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 <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a></code>, because it may not be there and servant would then
|
||||||
|
hand you <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#v:Nothing">Nothing</a></code>.</p><p>You can control how it'll be converted from <code>Text</code> to your type
|
||||||
|
by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>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...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:FromJSON">FromJSON</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> * (<a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a> * a) sublayout)</td><td class="doc"><p>If you use <code><a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a></code> 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 <code><a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a></code>.
|
||||||
|
This lets servant worry about extracting it from the request and turning
|
||||||
|
it into a value of the type you specify.</p><p>All it asks is for a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:FromJSON">FromJSON</a></code> instance.</p><p>Example:</p><pre>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...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> path, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) => <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:>)</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> path sublayout)</td><td class="doc"><p>Make sure the incoming request starts with <code>"/path"</code>, strip it and
|
||||||
|
pass the rest of the request path to <code>sublayout</code>.</p></td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
|
23
Servant-Utils-Links.html
Normal file
23
Servant-Utils-Links.html
Normal file
File diff suppressed because one or more lines are too long
15
Servant-Utils-StaticFiles.html
Normal file
15
Servant-Utils-StaticFiles.html
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.Utils.StaticFiles</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();setSynopsis("mini_Servant-Utils-StaticFiles.html");};
|
||||||
|
//]]>
|
||||||
|
</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-Utils-StaticFiles.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.Utils.StaticFiles</p></div><div id="description"><p class="caption">Description</p><div class="doc"><p>This module defines a sever-side handler that lets you serve static files.</p><ul><li><code><a href="Servant-Utils-StaticFiles.html#v:serveDirectory">serveDirectory</a></code> lets you serve anything that lives under a particular
|
||||||
|
directory on your filesystem.</li></ul></div></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><a href="#v:serveDirectory">serveDirectory</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:FilePath">FilePath</a> -> <a href="Servant-Server.html#t:Server">Server</a> <a href="Servant-API-Raw.html#t:Raw">Raw</a></li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><a name="v:serveDirectory" class="def">serveDirectory</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:FilePath">FilePath</a> -> <a href="Servant-Server.html#t:Server">Server</a> <a href="Servant-API-Raw.html#t:Raw">Raw</a> <a href="src/Servant-Utils-StaticFiles.html#serveDirectory" class="link">Source</a></p><div class="doc"><p>Serve anything under the specified directory as a <code><a href="Servant-API-Raw.html#t:Raw">Raw</a></code> endpoint.</p><pre>type MyApi = "static" :> Raw
|
||||||
|
|
||||||
|
server :: Server MyApi
|
||||||
|
server = serveDirectory "/var/www"
|
||||||
|
</pre><p>would capture any request to <code>/static/<something></code> and look for
|
||||||
|
<code><something></code> under <code>/var/www</code>.</p><p>It will do its best to guess the MIME type for that file, based on the extension,
|
||||||
|
and send an appropriate <em>Content-Type</em> header if possible.</p><p>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 <em>/static/</em> prefix. In that case, remember to put the <code><a href="Servant-Utils-StaticFiles.html#v:serveDirectory">serveDirectory</a></code>
|
||||||
|
handler in the last position, because <em>servant</em> will try to match the handlers
|
||||||
|
in order.</p></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
|
6
Servant.html
Normal file
6
Servant.html
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();setSynopsis("mini_Servant.html");};
|
||||||
|
//]]>
|
||||||
|
</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short">module <a href="Servant-API.html">Servant.API</a></li><li class="src short">module <a href="Servant-Server.html">Servant.Server</a></li><li class="src short">module <a href="Servant-Common-Text.html">Servant.Common.Text</a></li><li class="src short">module <a href="Servant-QQ.html">Servant.QQ</a></li><li class="src short">module <a href="Servant-Utils-Links.html">Servant.Utils.Links</a></li><li class="src short">module <a href="Servant-Utils-StaticFiles.html">Servant.Utils.StaticFiles</a></li><li class="src short"><span class="keyword">data</span> <a href="#t:Proxy">Proxy</a> t :: k -> * = <a href="#v:Proxy">Proxy</a></li></ul></div><div id="interface"><h1>Documentation</h1><div class="doc"><p>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).</p></div><div class="top"><p class="src">module <a href="Servant-API.html">Servant.API</a></p></div><div class="doc"><p>For implementing servers for servant APIs.</p></div><div class="top"><p class="src">module <a href="Servant-Server.html">Servant.Server</a></p></div><div class="doc"><p>Using your types in request paths and query string parameters</p></div><div class="top"><p class="src">module <a href="Servant-Common-Text.html">Servant.Common.Text</a></p></div><div class="doc"><p>Utilities on top of the servant core</p></div><div class="top"><p class="src">module <a href="Servant-QQ.html">Servant.QQ</a></p></div><div class="top"><p class="src">module <a href="Servant-Utils-Links.html">Servant.Utils.Links</a></p></div><div class="top"><p class="src">module <a href="Servant-Utils-StaticFiles.html">Servant.Utils.StaticFiles</a></p></div><div class="doc"><p>Useful re-exports</p></div><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:Proxy" class="def">Proxy</a> t :: k -> *</p><div class="doc"><p>A concrete, poly-kinded proxy type</p></div><div class="subs constructors"><p class="caption">Constructors</p><table><tr><td class="src"><a name="v:Proxy" class="def">Proxy</a></td><td class="doc empty"> </td></tr></table></div><div class="subs instances"><p id="control.i:Proxy" class="caption collapser" onclick="toggleSection('i:Proxy')">Instances</p><div id="section.i:Proxy" class="show"><table><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Control-Monad.html#t:Monad">Monad</a> (<a href="Servant.html#t:Proxy">Proxy</a> *)</td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Control-Monad.html#t:Functor">Functor</a> (<a href="Servant.html#t:Proxy">Proxy</a> *)</td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Control-Applicative.html#t:Applicative">Applicative</a> (<a href="Servant.html#t:Proxy">Proxy</a> *)</td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Bounded">Bounded</a> (<a href="Servant.html#t:Proxy">Proxy</a> k s)</td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Enum">Enum</a> (<a href="Servant.html#t:Proxy">Proxy</a> k s)</td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Eq.html#t:Eq">Eq</a> (<a href="Servant.html#t:Proxy">Proxy</a> k s)</td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Ord.html#t:Ord">Ord</a> (<a href="Servant.html#t:Proxy">Proxy</a> k s)</td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Text-Read.html#t:Read">Read</a> (<a href="Servant.html#t:Proxy">Proxy</a> k s)</td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Text-Show.html#t:Show">Show</a> (<a href="Servant.html#t:Proxy">Proxy</a> k s)</td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Ix.html#t:Ix">Ix</a> (<a href="Servant.html#t:Proxy">Proxy</a> k s)</td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-Generics.html#t:Generic">Generic</a> (<a href="Servant.html#t:Proxy">Proxy</a> * t)</td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Monoid.html#t:Monoid">Monoid</a> (<a href="Servant.html#t:Proxy">Proxy</a> * s)</td><td class="doc empty"> </td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Typeable-Internal.html#t:Typeable">Typeable</a> (k -> *) (<a href="Servant.html#t:Proxy">Proxy</a> k)</td><td class="doc empty"> </td></tr><tr><td class="src"><span class="keyword">type</span> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-Generics.html#t:Rep">Rep</a> (<a href="Servant.html#t:Proxy">Proxy</a> k t) = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-Generics.html#t:D1">D1</a> D1Proxy (<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-Generics.html#t:C1">C1</a> C1_0Proxy <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-Generics.html#t:U1">U1</a>)</td><td class="doc empty"> </td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
|
4
doc-index.html
Normal file
4
doc-index.html
Normal file
File diff suppressed because one or more lines are too long
30
frames.html
Normal file
30
frames.html
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<!DOCTYPE html
|
||||||
|
PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title></title>
|
||||||
|
<script src="haddock-util.js" type="text/javascript"></script>
|
||||||
|
<script type="text/javascript"><!--
|
||||||
|
/*
|
||||||
|
|
||||||
|
The synopsis frame needs to be updated using javascript, so we hide
|
||||||
|
it by default and only show it if javascript is enabled.
|
||||||
|
|
||||||
|
TODO: provide some means to disable it.
|
||||||
|
*/
|
||||||
|
function load() {
|
||||||
|
var d = document.getElementById("inner-fs");
|
||||||
|
d.rows = "50%,50%";
|
||||||
|
postReframe();
|
||||||
|
}
|
||||||
|
--></script>
|
||||||
|
</head>
|
||||||
|
<frameset id="outer-fs" cols="25%,75%" onload="load()">
|
||||||
|
<frameset id="inner-fs" rows="100%,0%">
|
||||||
|
<frame src="index-frames.html" name="modules" />
|
||||||
|
<frame src="" name="synopsis" />
|
||||||
|
</frameset>
|
||||||
|
<frame src="index.html" name="main" />
|
||||||
|
</frameset>
|
||||||
|
</html>
|
344
haddock-util.js
Normal file
344
haddock-util.js
Normal file
|
@ -0,0 +1,344 @@
|
||||||
|
// Haddock JavaScript utilities
|
||||||
|
|
||||||
|
var rspace = /\s\s+/g,
|
||||||
|
rtrim = /^\s+|\s+$/g;
|
||||||
|
|
||||||
|
function spaced(s) { return (" " + s + " ").replace(rspace, " "); }
|
||||||
|
function trim(s) { return s.replace(rtrim, ""); }
|
||||||
|
|
||||||
|
function hasClass(elem, value) {
|
||||||
|
var className = spaced(elem.className || "");
|
||||||
|
return className.indexOf( " " + value + " " ) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addClass(elem, value) {
|
||||||
|
var className = spaced(elem.className || "");
|
||||||
|
if ( className.indexOf( " " + value + " " ) < 0 ) {
|
||||||
|
elem.className = trim(className + " " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeClass(elem, value) {
|
||||||
|
var className = spaced(elem.className || "");
|
||||||
|
className = className.replace(" " + value + " ", " ");
|
||||||
|
elem.className = trim(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleClass(elem, valueOn, valueOff, bool) {
|
||||||
|
if (bool == null) { bool = ! hasClass(elem, valueOn); }
|
||||||
|
if (bool) {
|
||||||
|
removeClass(elem, valueOff);
|
||||||
|
addClass(elem, valueOn);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
removeClass(elem, valueOn);
|
||||||
|
addClass(elem, valueOff);
|
||||||
|
}
|
||||||
|
return bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function makeClassToggle(valueOn, valueOff)
|
||||||
|
{
|
||||||
|
return function(elem, bool) {
|
||||||
|
return toggleClass(elem, valueOn, valueOff, bool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleShow = makeClassToggle("show", "hide");
|
||||||
|
toggleCollapser = makeClassToggle("collapser", "expander");
|
||||||
|
|
||||||
|
function toggleSection(id)
|
||||||
|
{
|
||||||
|
var b = toggleShow(document.getElementById("section." + id));
|
||||||
|
toggleCollapser(document.getElementById("control." + id), b);
|
||||||
|
rememberCollapsed(id, b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
var collapsed = {};
|
||||||
|
function rememberCollapsed(id, b)
|
||||||
|
{
|
||||||
|
if(b)
|
||||||
|
delete collapsed[id]
|
||||||
|
else
|
||||||
|
collapsed[id] = null;
|
||||||
|
|
||||||
|
var sections = [];
|
||||||
|
for(var i in collapsed)
|
||||||
|
{
|
||||||
|
if(collapsed.hasOwnProperty(i))
|
||||||
|
sections.push(i);
|
||||||
|
}
|
||||||
|
// cookie specific to this page; don't use setCookie which sets path=/
|
||||||
|
document.cookie = "collapsed=" + escape(sections.join('+'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function restoreCollapsed()
|
||||||
|
{
|
||||||
|
var cookie = getCookie("collapsed");
|
||||||
|
if(!cookie)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var ids = cookie.split('+');
|
||||||
|
for(var i in ids)
|
||||||
|
{
|
||||||
|
if(document.getElementById("section." + ids[i]))
|
||||||
|
toggleSection(ids[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCookie(name, value) {
|
||||||
|
document.cookie = name + "=" + escape(value) + ";path=/;";
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearCookie(name) {
|
||||||
|
document.cookie = name + "=;path=/;expires=Thu, 01-Jan-1970 00:00:01 GMT;";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCookie(name) {
|
||||||
|
var nameEQ = name + "=";
|
||||||
|
var ca = document.cookie.split(';');
|
||||||
|
for(var i=0;i < ca.length;i++) {
|
||||||
|
var c = ca[i];
|
||||||
|
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
||||||
|
if (c.indexOf(nameEQ) == 0) {
|
||||||
|
return unescape(c.substring(nameEQ.length,c.length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var max_results = 75; // 50 is not enough to search for map in the base libraries
|
||||||
|
var shown_range = null;
|
||||||
|
var last_search = null;
|
||||||
|
|
||||||
|
function quick_search()
|
||||||
|
{
|
||||||
|
perform_search(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function full_search()
|
||||||
|
{
|
||||||
|
perform_search(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function perform_search(full)
|
||||||
|
{
|
||||||
|
var text = document.getElementById("searchbox").value.toLowerCase();
|
||||||
|
if (text == last_search && !full) return;
|
||||||
|
last_search = text;
|
||||||
|
|
||||||
|
var table = document.getElementById("indexlist");
|
||||||
|
var status = document.getElementById("searchmsg");
|
||||||
|
var children = table.firstChild.childNodes;
|
||||||
|
|
||||||
|
// first figure out the first node with the prefix
|
||||||
|
var first = bisect(-1);
|
||||||
|
var last = (first == -1 ? -1 : bisect(1));
|
||||||
|
|
||||||
|
if (first == -1)
|
||||||
|
{
|
||||||
|
table.className = "";
|
||||||
|
status.innerHTML = "No results found, displaying all";
|
||||||
|
}
|
||||||
|
else if (first == 0 && last == children.length - 1)
|
||||||
|
{
|
||||||
|
table.className = "";
|
||||||
|
status.innerHTML = "";
|
||||||
|
}
|
||||||
|
else if (last - first >= max_results && !full)
|
||||||
|
{
|
||||||
|
table.className = "";
|
||||||
|
status.innerHTML = "More than " + max_results + ", press Search to display";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// decide what you need to clear/show
|
||||||
|
if (shown_range)
|
||||||
|
setclass(shown_range[0], shown_range[1], "indexrow");
|
||||||
|
setclass(first, last, "indexshow");
|
||||||
|
shown_range = [first, last];
|
||||||
|
table.className = "indexsearch";
|
||||||
|
status.innerHTML = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function setclass(first, last, status)
|
||||||
|
{
|
||||||
|
for (var i = first; i <= last; i++)
|
||||||
|
{
|
||||||
|
children[i].className = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// do a binary search, treating 0 as ...
|
||||||
|
// return either -1 (no 0's found) or location of most far match
|
||||||
|
function bisect(dir)
|
||||||
|
{
|
||||||
|
var first = 0, finish = children.length - 1;
|
||||||
|
var mid, success = false;
|
||||||
|
|
||||||
|
while (finish - first > 3)
|
||||||
|
{
|
||||||
|
mid = Math.floor((finish + first) / 2);
|
||||||
|
|
||||||
|
var i = checkitem(mid);
|
||||||
|
if (i == 0) i = dir;
|
||||||
|
if (i == -1)
|
||||||
|
finish = mid;
|
||||||
|
else
|
||||||
|
first = mid;
|
||||||
|
}
|
||||||
|
var a = (dir == 1 ? first : finish);
|
||||||
|
var b = (dir == 1 ? finish : first);
|
||||||
|
for (var i = b; i != a - dir; i -= dir)
|
||||||
|
{
|
||||||
|
if (checkitem(i) == 0) return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// from an index, decide what the result is
|
||||||
|
// 0 = match, -1 is lower, 1 is higher
|
||||||
|
function checkitem(i)
|
||||||
|
{
|
||||||
|
var s = getitem(i).toLowerCase().substr(0, text.length);
|
||||||
|
if (s == text) return 0;
|
||||||
|
else return (s > text ? -1 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// from an index, get its string
|
||||||
|
// this abstracts over alternates
|
||||||
|
function getitem(i)
|
||||||
|
{
|
||||||
|
for ( ; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var s = children[i].firstChild.firstChild.data;
|
||||||
|
if (s.indexOf(' ') == -1)
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return ""; // should never be reached
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSynopsis(filename) {
|
||||||
|
if (parent.window.synopsis) {
|
||||||
|
if (parent.window.synopsis.location.replace) {
|
||||||
|
// In Firefox this avoids adding the change to the history.
|
||||||
|
parent.window.synopsis.location.replace(filename);
|
||||||
|
} else {
|
||||||
|
parent.window.synopsis.location = filename;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addMenuItem(html) {
|
||||||
|
var menu = document.getElementById("page-menu");
|
||||||
|
if (menu) {
|
||||||
|
var btn = menu.firstChild.cloneNode(false);
|
||||||
|
btn.innerHTML = html;
|
||||||
|
menu.appendChild(btn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function adjustForFrames() {
|
||||||
|
var bodyCls;
|
||||||
|
|
||||||
|
if (parent.location.href == window.location.href) {
|
||||||
|
// not in frames, so add Frames button
|
||||||
|
addMenuItem("<a href='#' onclick='reframe();return true;'>Frames</a>");
|
||||||
|
bodyCls = "no-frame";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bodyCls = "in-frame";
|
||||||
|
}
|
||||||
|
addClass(document.body, bodyCls);
|
||||||
|
}
|
||||||
|
|
||||||
|
function reframe() {
|
||||||
|
setCookie("haddock-reframe", document.URL);
|
||||||
|
window.location = "frames.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
function postReframe() {
|
||||||
|
var s = getCookie("haddock-reframe");
|
||||||
|
if (s) {
|
||||||
|
parent.window.main.location = s;
|
||||||
|
clearCookie("haddock-reframe");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function styles() {
|
||||||
|
var i, a, es = document.getElementsByTagName("link"), rs = [];
|
||||||
|
for (i = 0; a = es[i]; i++) {
|
||||||
|
if(a.rel.indexOf("style") != -1 && a.title) {
|
||||||
|
rs.push(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addStyleMenu() {
|
||||||
|
var as = styles();
|
||||||
|
var i, a, btns = "";
|
||||||
|
for(i=0; a = as[i]; i++) {
|
||||||
|
btns += "<li><a href='#' onclick=\"setActiveStyleSheet('"
|
||||||
|
+ a.title + "'); return false;\">"
|
||||||
|
+ a.title + "</a></li>"
|
||||||
|
}
|
||||||
|
if (as.length > 1) {
|
||||||
|
var h = "<div id='style-menu-holder'>"
|
||||||
|
+ "<a href='#' onclick='styleMenu(); return false;'>Style ▾</a>"
|
||||||
|
+ "<ul id='style-menu' class='hide'>" + btns + "</ul>"
|
||||||
|
+ "</div>";
|
||||||
|
addMenuItem(h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setActiveStyleSheet(title) {
|
||||||
|
var as = styles();
|
||||||
|
var i, a, found;
|
||||||
|
for(i=0; a = as[i]; i++) {
|
||||||
|
a.disabled = true;
|
||||||
|
// need to do this always, some browsers are edge triggered
|
||||||
|
if(a.title == title) {
|
||||||
|
found = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
found.disabled = false;
|
||||||
|
setCookie("haddock-style", title);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
as[0].disabled = false;
|
||||||
|
clearCookie("haddock-style");
|
||||||
|
}
|
||||||
|
styleMenu(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetStyle() {
|
||||||
|
var s = getCookie("haddock-style");
|
||||||
|
if (s) setActiveStyleSheet(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function styleMenu(show) {
|
||||||
|
var m = document.getElementById('style-menu');
|
||||||
|
if (m) toggleShow(m, show);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function pageLoad() {
|
||||||
|
addStyleMenu();
|
||||||
|
adjustForFrames();
|
||||||
|
resetStyle();
|
||||||
|
restoreCollapsed();
|
||||||
|
}
|
||||||
|
|
BIN
hslogo-16.png
Normal file
BIN
hslogo-16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
4
index-frames.html
Normal file
4
index-frames.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>servant-0.2</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-list"><p class="caption">Modules</p><ul><li class="module"><a href="Servant.html" target="main">Servant</a></li><li class="module"><a href="Servant-API.html" target="main">Servant.API</a></li><li class="module"><a href="Servant-API-Alternative.html" target="main">Servant.API.Alternative</a></li><li class="module"><a href="Servant-API-Capture.html" target="main">Servant.API.Capture</a></li><li class="module"><a href="Servant-API-Delete.html" target="main">Servant.API.Delete</a></li><li class="module"><a href="Servant-API-Get.html" target="main">Servant.API.Get</a></li><li class="module"><a href="Servant-API-Post.html" target="main">Servant.API.Post</a></li><li class="module"><a href="Servant-API-Put.html" target="main">Servant.API.Put</a></li><li class="module"><a href="Servant-API-QueryParam.html" target="main">Servant.API.QueryParam</a></li><li class="module"><a href="Servant-API-Raw.html" target="main">Servant.API.Raw</a></li><li class="module"><a href="Servant-API-ReqBody.html" target="main">Servant.API.ReqBody</a></li><li class="module"><a href="Servant-API-Sub.html" target="main">Servant.API.Sub</a></li><li class="module"><a href="Servant-Common-Text.html" target="main">Servant.Common.Text</a></li><li class="module"><a href="Servant-QQ.html" target="main">Servant.QQ</a></li><li class="module"><a href="Servant-Server.html" target="main">Servant.Server</a></li><li class="module"><a href="Servant-Utils-Links.html" target="main">Servant.Utils.Links</a></li><li class="module"><a href="Servant-Utils-StaticFiles.html" target="main">Servant.Utils.StaticFiles</a></li></ul></div></body></html>
|
4
index.html
Normal file
4
index.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>servant-0.2</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="description"><h1>servant-0.2</h1><div class="doc empty"> </div></div><div id="module-list"><p class="caption">Modules</p><ul><li><span class="module"><span id="control.n.1" class="collapser" onclick="toggleSection('n.1')"> </span><a href="Servant.html">Servant</a></span><ul id="section.n.1" class="show"><li><span class="module"><span id="control.n.1.1" class="collapser" onclick="toggleSection('n.1.1')"> </span><a href="Servant-API.html">Servant.API</a></span><ul id="section.n.1.1" class="show"><li><span class="module"><a href="Servant-API-Alternative.html">Servant.API.Alternative</a></span></li><li><span class="module"><a href="Servant-API-Capture.html">Servant.API.Capture</a></span></li><li><span class="module"><a href="Servant-API-Delete.html">Servant.API.Delete</a></span></li><li><span class="module"><a href="Servant-API-Get.html">Servant.API.Get</a></span></li><li><span class="module"><a href="Servant-API-Post.html">Servant.API.Post</a></span></li><li><span class="module"><a href="Servant-API-Put.html">Servant.API.Put</a></span></li><li><span class="module"><a href="Servant-API-QueryParam.html">Servant.API.QueryParam</a></span></li><li><span class="module"><a href="Servant-API-Raw.html">Servant.API.Raw</a></span></li><li><span class="module"><a href="Servant-API-ReqBody.html">Servant.API.ReqBody</a></span></li><li><span class="module"><a href="Servant-API-Sub.html">Servant.API.Sub</a></span></li></ul></li><li><span id="control.n.1.2" class="module collapser" onclick="toggleSection('n.1.2')">Common</span><ul id="section.n.1.2" class="show"><li><span class="module"><a href="Servant-Common-Text.html">Servant.Common.Text</a></span></li></ul></li><li><span class="module"><a href="Servant-QQ.html">Servant.QQ</a></span></li><li><span class="module"><a href="Servant-Server.html">Servant.Server</a></span></li><li><span id="control.n.1.5" class="module collapser" onclick="toggleSection('n.1.5')">Utils</span><ul id="section.n.1.5" class="show"><li><span class="module"><a href="Servant-Utils-Links.html">Servant.Utils.Links</a></span></li><li><span class="module"><a href="Servant-Utils-StaticFiles.html">Servant.Utils.StaticFiles</a></span></li></ul></li></ul></li></ul></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
|
4
mini_Servant-API-Alternative.html
Normal file
4
mini_Servant-API-Alternative.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Alternative</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.Alternative</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> a <a href="Servant-API-Alternative.html#t::-60--124--62-" target="main">:<|></a> b</p></div></div></body></html>
|
4
mini_Servant-API-Capture.html
Normal file
4
mini_Servant-API-Capture.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Capture</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.Capture</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-Capture.html#t:Capture" target="main">Capture</a> sym a</p></div></div></body></html>
|
4
mini_Servant-API-Delete.html
Normal file
4
mini_Servant-API-Delete.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Delete</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.Delete</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-Delete.html#t:Delete" target="main">Delete</a></p></div></div></body></html>
|
4
mini_Servant-API-Get.html
Normal file
4
mini_Servant-API-Get.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Get</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.Get</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-Get.html#t:Get" target="main">Get</a> a</p></div></div></body></html>
|
4
mini_Servant-API-Post.html
Normal file
4
mini_Servant-API-Post.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Post</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.Post</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-Post.html#t:Post" target="main">Post</a> a</p></div></div></body></html>
|
4
mini_Servant-API-Put.html
Normal file
4
mini_Servant-API-Put.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Put</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.Put</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-Put.html#t:Put" target="main">Put</a> a</p></div></div></body></html>
|
4
mini_Servant-API-QueryParam.html
Normal file
4
mini_Servant-API-QueryParam.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.QueryParam</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.QueryParam</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-QueryParam.html#t:QueryParam" target="main">QueryParam</a> sym a</p></div><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-QueryParam.html#t:QueryParams" target="main">QueryParams</a> sym a</p></div><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-QueryParam.html#t:QueryFlag" target="main">QueryFlag</a> sym</p></div></div></body></html>
|
4
mini_Servant-API-Raw.html
Normal file
4
mini_Servant-API-Raw.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Raw</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.Raw</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-Raw.html#t:Raw" target="main">Raw</a></p></div></div></body></html>
|
4
mini_Servant-API-ReqBody.html
Normal file
4
mini_Servant-API-ReqBody.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.ReqBody</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.ReqBody</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-ReqBody.html#t:ReqBody" target="main">ReqBody</a> a</p></div></div></body></html>
|
4
mini_Servant-API-Sub.html
Normal file
4
mini_Servant-API-Sub.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Sub</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.Sub</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> path <a href="Servant-API-Sub.html#t::-62-" target="main">:></a> a</p></div></div></body></html>
|
4
mini_Servant-API.html
Normal file
4
mini_Servant-API.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API</p></div><div id="interface"><h1>Combinators</h1><h1>Accessing information from the request</h1><h1>Actual endpoints, distinguished by HTTP method</h1><h1>Untyped endpoints</h1><h1>Utilities</h1></div></body></html>
|
4
mini_Servant-Common-Text.html
Normal file
4
mini_Servant-Common-Text.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.Common.Text</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.Common.Text</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">class</span> <a href="Servant-Common-Text.html#t:FromText" target="main">FromText</a> a</p></div><div class="top"><p class="src"><span class="keyword">class</span> <a href="Servant-Common-Text.html#t:ToText" target="main">ToText</a> a</p></div></div></body></html>
|
4
mini_Servant-QQ.html
Normal file
4
mini_Servant-QQ.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.QQ</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.QQ</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">class</span> <a href="Servant-QQ.html#t:ExpSYM" target="main">ExpSYM</a> repr' repr</p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:-62-:" target="main">(>:)</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:parseMethod" target="main">parseMethod</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:parseUrlSegment" target="main">parseUrlSegment</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:parseUrl" target="main">parseUrl</a></p></div><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-QQ.html#t:Typ" target="main">Typ</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:parseTyp" target="main">parseTyp</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:parseEntry" target="main">parseEntry</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:blockComment" target="main">blockComment</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:inlineComment" target="main">inlineComment</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:eol" target="main">eol</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:eols" target="main">eols</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:parseAll" target="main">parseAll</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:sitemap" target="main">sitemap</a></p></div></div></body></html>
|
4
mini_Servant-Server.html
Normal file
4
mini_Servant-Server.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.Server</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.Server</p></div><div id="interface"><h1>Implementing Servers</h1><div class="top"><p class="src"><a href="Servant-Server.html#v:serve" target="main">serve</a></p></div><div class="top"><p class="src"><a href="Servant-Server.html#v:toApplication" target="main">toApplication</a></p></div><h1>Route mismatch</h1><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-Server.html#t:RouteMismatch" target="main">RouteMismatch</a></p></div><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-Server.html#t:RouteResult" target="main">RouteResult</a> a</p></div><div class="top"><p class="src"><a href="Servant-Server.html#v:failWith" target="main">failWith</a></p></div><div class="top"><p class="src"><a href="Servant-Server.html#v:succeedWith" target="main">succeedWith</a></p></div><div class="top"><p class="src"><a href="Servant-Server.html#v:isMismatch" target="main">isMismatch</a></p></div><div class="top"><p class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:RoutingApplication" target="main">RoutingApplication</a></p></div><div class="top"><p class="src"><span class="keyword">class</span> <a href="Servant-Server.html#t:HasServer" target="main">HasServer</a> layout</p></div></div></body></html>
|
4
mini_Servant-Utils-Links.html
Normal file
4
mini_Servant-Utils-Links.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.Utils.Links</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.Utils.Links</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">type family</span> <a href="#t:Or">Or</a> a b</p></div><div class="top"><p class="src"><span class="keyword">type family</span> <a href="#t:And">And</a> a b</p></div><div class="top"><p class="src"><span class="keyword">type family</span> <a href="#t:IsElem">IsElem</a> a s</p></div><div class="top"><p class="src"><span class="keyword">type family</span> <a href="#t:IsLink-39--39-">IsLink''</a> l</p></div><div class="top"><p class="src"><span class="keyword">type family</span> <a href="#t:IsLink-39-">IsLink'</a> e</p></div><div class="top"><p class="src"><span class="keyword">type family</span> <a href="#t:IsLink">IsLink</a> e</p></div><div class="top"><p class="src"><span class="keyword">class</span> <a href="Servant-Utils-Links.html#t:ValidLinkIn" target="main">ValidLinkIn</a> f s</p></div><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-Utils-Links.html#t:Link" target="main">Link</a></p></div><div class="top"><p class="src"><span class="keyword">class</span> <a href="Servant-Utils-Links.html#t:VLinkHelper" target="main">VLinkHelper</a> f</p></div></div></body></html>
|
4
mini_Servant-Utils-StaticFiles.html
Normal file
4
mini_Servant-Utils-StaticFiles.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.Utils.StaticFiles</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.Utils.StaticFiles</p></div><div id="interface"><div class="top"><p class="src"><a href="Servant-Utils-StaticFiles.html#v:serveDirectory" target="main">serveDirectory</a></p></div></div></body></html>
|
4
mini_Servant.html
Normal file
4
mini_Servant.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
|
||||||
|
window.onload = function () {pageLoad();};
|
||||||
|
//]]>
|
||||||
|
</script></head><body id="mini"><div id="module-header"><p class="caption">Servant</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant.html#t:Proxy" target="main">Proxy</a> t</p></div></div></body></html>
|
BIN
minus.gif
Normal file
BIN
minus.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 56 B |
577
ocean.css
Normal file
577
ocean.css
Normal file
|
@ -0,0 +1,577 @@
|
||||||
|
/* @group Fundamentals */
|
||||||
|
|
||||||
|
* { margin: 0; padding: 0 }
|
||||||
|
|
||||||
|
/* Is this portable? */
|
||||||
|
html {
|
||||||
|
background-color: white;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: white;
|
||||||
|
color: black;
|
||||||
|
text-align: left;
|
||||||
|
min-height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0.8em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul, ol {
|
||||||
|
margin: 0.8em 0 0.8em 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl {
|
||||||
|
margin: 0.8em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
dd {
|
||||||
|
margin-left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
a { text-decoration: none; }
|
||||||
|
a[href]:link { color: rgb(196,69,29); }
|
||||||
|
a[href]:visited { color: rgb(171,105,84); }
|
||||||
|
a[href]:hover { text-decoration:underline; }
|
||||||
|
|
||||||
|
/* @end */
|
||||||
|
|
||||||
|
/* @group Fonts & Sizes */
|
||||||
|
|
||||||
|
/* Basic technique & IE workarounds from YUI 3
|
||||||
|
For reasons, see:
|
||||||
|
http://yui.yahooapis.com/3.1.1/build/cssfonts/fonts.css
|
||||||
|
*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
font:13px/1.4 sans-serif;
|
||||||
|
*font-size:small; /* for IE */
|
||||||
|
*font:x-small; /* for IE in quirks mode */
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 { font-size: 146.5%; /* 19pt */ }
|
||||||
|
h2 { font-size: 131%; /* 17pt */ }
|
||||||
|
h3 { font-size: 116%; /* 15pt */ }
|
||||||
|
h4 { font-size: 100%; /* 13pt */ }
|
||||||
|
h5 { font-size: 100%; /* 13pt */ }
|
||||||
|
|
||||||
|
select, input, button, textarea {
|
||||||
|
font:99% sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
font-size:inherit;
|
||||||
|
font:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre, code, kbd, samp, tt, .src {
|
||||||
|
font-family:monospace;
|
||||||
|
*font-size:108%;
|
||||||
|
line-height: 124%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.links, .link {
|
||||||
|
font-size: 85%; /* 11pt */
|
||||||
|
}
|
||||||
|
|
||||||
|
#module-header .caption {
|
||||||
|
font-size: 182%; /* 24pt */
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
font-size: 85%; /* 11pt */
|
||||||
|
}
|
||||||
|
|
||||||
|
#table-of-contents, #synopsis {
|
||||||
|
/* font-size: 85%; /* 11pt */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @end */
|
||||||
|
|
||||||
|
/* @group Common */
|
||||||
|
|
||||||
|
.caption, h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-weight: bold;
|
||||||
|
color: rgb(78,98,114);
|
||||||
|
margin: 0.8em 0 0.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
* + h1, * + h2, * + h3, * + h4, * + h5, * + h6 {
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 + h2, h2 + h3, h3 + h4, h4 + h5, h5 + h6 {
|
||||||
|
margin-top: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.links {
|
||||||
|
list-style: none;
|
||||||
|
text-align: left;
|
||||||
|
float: right;
|
||||||
|
display: inline-table;
|
||||||
|
margin: 0 0 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.links li {
|
||||||
|
display: inline;
|
||||||
|
border-left: 1px solid #d5d5d5;
|
||||||
|
white-space: nowrap;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.links li a {
|
||||||
|
padding: 0.2em 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide { display: none; }
|
||||||
|
.show { display: inherit; }
|
||||||
|
.clear { clear: both; }
|
||||||
|
|
||||||
|
.collapser {
|
||||||
|
background-image: url(minus.gif);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
.expander {
|
||||||
|
background-image: url(plus.gif);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
p.caption.collapser,
|
||||||
|
p.caption.expander {
|
||||||
|
background-position: 0 0.4em;
|
||||||
|
}
|
||||||
|
.collapser, .expander {
|
||||||
|
padding-left: 14px;
|
||||||
|
margin-left: -14px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
padding: 0.25em;
|
||||||
|
margin: 0.8em 0;
|
||||||
|
background: rgb(229,237,244);
|
||||||
|
overflow: auto;
|
||||||
|
border-bottom: 0.25em solid white;
|
||||||
|
/* white border adds some space below the box to compensate
|
||||||
|
for visual extra space that paragraphs have between baseline
|
||||||
|
and the bounding box */
|
||||||
|
}
|
||||||
|
|
||||||
|
.src {
|
||||||
|
background: #f0f0f0;
|
||||||
|
padding: 0.2em 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.keyword { font-weight: normal; }
|
||||||
|
.def { font-weight: bold; }
|
||||||
|
|
||||||
|
|
||||||
|
/* @end */
|
||||||
|
|
||||||
|
/* @group Page Structure */
|
||||||
|
|
||||||
|
#content {
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 2em 6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#package-header {
|
||||||
|
background: rgb(41,56,69);
|
||||||
|
border-top: 5px solid rgb(78,98,114);
|
||||||
|
color: #ddd;
|
||||||
|
padding: 0.2em;
|
||||||
|
position: relative;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#package-header .caption {
|
||||||
|
background: url(hslogo-16.png) no-repeat 0em;
|
||||||
|
color: white;
|
||||||
|
margin: 0 2em;
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
padding-left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#package-header a:link, #package-header a:visited { color: white; }
|
||||||
|
#package-header a:hover { background: rgb(78,98,114); }
|
||||||
|
|
||||||
|
#module-header .caption {
|
||||||
|
color: rgb(78,98,114);
|
||||||
|
font-weight: bold;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.info {
|
||||||
|
float: right;
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
color: rgb(78,98,114);
|
||||||
|
background-color: #fff;
|
||||||
|
max-width: 40%;
|
||||||
|
border-spacing: 0;
|
||||||
|
position: relative;
|
||||||
|
top: -0.5em;
|
||||||
|
margin: 0 0 0 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info th {
|
||||||
|
padding: 0 1em 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#style-menu-holder {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
#style-menu {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
overflow: visible;
|
||||||
|
background: #374c5e;
|
||||||
|
margin: 0;
|
||||||
|
text-align: center;
|
||||||
|
right: 0;
|
||||||
|
padding: 0;
|
||||||
|
top: 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#style-menu li {
|
||||||
|
display: list-item;
|
||||||
|
border-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
color: #000;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#style-menu li + li {
|
||||||
|
border-top: 1px solid #919191;
|
||||||
|
}
|
||||||
|
|
||||||
|
#style-menu a {
|
||||||
|
width: 6em;
|
||||||
|
padding: 3px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer {
|
||||||
|
background: #ddd;
|
||||||
|
border-top: 1px solid #aaa;
|
||||||
|
padding: 0.5em 0;
|
||||||
|
color: #666;
|
||||||
|
text-align: center;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @end */
|
||||||
|
|
||||||
|
/* @group Front Matter */
|
||||||
|
|
||||||
|
#table-of-contents {
|
||||||
|
float: right;
|
||||||
|
clear: right;
|
||||||
|
background: #faf9dc;
|
||||||
|
border: 1px solid #d8d7ad;
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
max-width: 20em;
|
||||||
|
margin: 0.5em 0 1em 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#table-of-contents .caption {
|
||||||
|
text-align: center;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#table-of-contents ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#table-of-contents ul ul {
|
||||||
|
margin-left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#description .caption {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#synopsis {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-frame #synopsis {
|
||||||
|
display: block;
|
||||||
|
position: fixed;
|
||||||
|
right: 0;
|
||||||
|
height: 80%;
|
||||||
|
top: 10%;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#synopsis .caption {
|
||||||
|
float: left;
|
||||||
|
width: 29px;
|
||||||
|
color: rgba(255,255,255,0);
|
||||||
|
height: 110px;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#synopsis p.caption.collapser {
|
||||||
|
background: url(synopsis.png) no-repeat -64px -8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#synopsis p.caption.expander {
|
||||||
|
background: url(synopsis.png) no-repeat 0px -8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#synopsis ul {
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
padding: 0.5em;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#synopsis ul ul {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#synopsis ul,
|
||||||
|
#synopsis ul li.src {
|
||||||
|
background-color: #faf9dc;
|
||||||
|
white-space: nowrap;
|
||||||
|
list-style: none;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @end */
|
||||||
|
|
||||||
|
/* @group Main Content */
|
||||||
|
|
||||||
|
#interface div.top { margin: 2em 0; }
|
||||||
|
#interface h1 + div.top,
|
||||||
|
#interface h2 + div.top,
|
||||||
|
#interface h3 + div.top,
|
||||||
|
#interface h4 + div.top,
|
||||||
|
#interface h5 + div.top {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
#interface p.src .link {
|
||||||
|
float: right;
|
||||||
|
color: #919191;
|
||||||
|
border-left: 1px solid #919191;
|
||||||
|
background: #f0f0f0;
|
||||||
|
padding: 0 0.5em 0.2em;
|
||||||
|
margin: 0 -0.5em 0 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#interface span.fixity {
|
||||||
|
color: #919191;
|
||||||
|
border-left: 1px solid #919191;
|
||||||
|
padding: 0.2em 0.5em 0.2em 0.5em;
|
||||||
|
margin: 0 -1em 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#interface span.rightedge {
|
||||||
|
border-left: 1px solid #919191;
|
||||||
|
padding: 0.2em 0 0.2em 0;
|
||||||
|
margin: 0 0 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#interface table { border-spacing: 2px; }
|
||||||
|
#interface td {
|
||||||
|
vertical-align: top;
|
||||||
|
padding-left: 0.5em;
|
||||||
|
}
|
||||||
|
#interface td.src {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
#interface td.doc p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#interface td.doc p + p {
|
||||||
|
margin-top: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subs dl {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subs dt {
|
||||||
|
float: left;
|
||||||
|
clear: left;
|
||||||
|
display: block;
|
||||||
|
margin: 1px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subs dd {
|
||||||
|
float: right;
|
||||||
|
width: 90%;
|
||||||
|
display: block;
|
||||||
|
padding-left: 0.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subs dd.empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subs dd p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Render short-style data instances */
|
||||||
|
.inst ul {
|
||||||
|
height: 100%;
|
||||||
|
padding: 0.5em;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inst, .inst li {
|
||||||
|
list-style: none;
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top p.src {
|
||||||
|
border-top: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subs, .doc {
|
||||||
|
/* use this selector for one level of indent */
|
||||||
|
padding-left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arguments {
|
||||||
|
margin-top: -0.4em;
|
||||||
|
}
|
||||||
|
.arguments .caption {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fields { padding-left: 1em; }
|
||||||
|
|
||||||
|
.fields .caption { display: none; }
|
||||||
|
|
||||||
|
.fields p { margin: 0 0; }
|
||||||
|
|
||||||
|
/* this seems bulky to me
|
||||||
|
.methods, .constructors {
|
||||||
|
background: #f8f8f8;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* @end */
|
||||||
|
|
||||||
|
/* @group Auxillary Pages */
|
||||||
|
|
||||||
|
|
||||||
|
.extension-list {
|
||||||
|
list-style-type: none;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mini {
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 1em 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mini > * {
|
||||||
|
font-size: 93%; /* 12pt */
|
||||||
|
}
|
||||||
|
|
||||||
|
#mini #module-list .caption,
|
||||||
|
#mini #module-header .caption {
|
||||||
|
font-size: 125%; /* 15pt */
|
||||||
|
}
|
||||||
|
|
||||||
|
#mini #interface h1,
|
||||||
|
#mini #interface h2,
|
||||||
|
#mini #interface h3,
|
||||||
|
#mini #interface h4 {
|
||||||
|
font-size: 109%; /* 13pt */
|
||||||
|
margin: 1em 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mini #interface .top,
|
||||||
|
#mini #interface .src {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mini #module-list ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#alphabet ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0.5em 0 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#alphabet li {
|
||||||
|
display: inline;
|
||||||
|
margin: 0 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#alphabet a {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#index .caption,
|
||||||
|
#module-list .caption { font-size: 131%; /* 17pt */ }
|
||||||
|
|
||||||
|
#index table {
|
||||||
|
margin-left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#index .src {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
#index .alt {
|
||||||
|
font-size: 77%; /* 10pt */
|
||||||
|
font-style: italic;
|
||||||
|
padding-left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#index td + td {
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#module-list ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0 0 0 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#module-list li {
|
||||||
|
clear: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#module-list span.collapser,
|
||||||
|
#module-list span.expander {
|
||||||
|
background-position: 0 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#module-list .package {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @end */
|
BIN
plus.gif
Normal file
BIN
plus.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 59 B |
BIN
servant.haddock
Normal file
BIN
servant.haddock
Normal file
Binary file not shown.
611
servant.txt
Normal file
611
servant.txt
Normal file
|
@ -0,0 +1,611 @@
|
||||||
|
-- Hoogle documentation, generated by Haddock
|
||||||
|
-- See Hoogle, http://www.haskell.org/hoogle/
|
||||||
|
|
||||||
|
|
||||||
|
@package servant
|
||||||
|
@version 0.2
|
||||||
|
|
||||||
|
module Servant.Common.Text
|
||||||
|
|
||||||
|
-- | For getting values from url captures and query string parameters
|
||||||
|
class FromText a
|
||||||
|
fromText :: FromText a => Text -> Maybe a
|
||||||
|
|
||||||
|
-- | For putting values in paths and query string parameters
|
||||||
|
class ToText a
|
||||||
|
toText :: ToText a => a -> Text
|
||||||
|
instance ToText Float
|
||||||
|
instance FromText Float
|
||||||
|
instance ToText Double
|
||||||
|
instance FromText Double
|
||||||
|
instance ToText Integer
|
||||||
|
instance FromText Integer
|
||||||
|
instance ToText Word64
|
||||||
|
instance FromText Word64
|
||||||
|
instance ToText Word32
|
||||||
|
instance FromText Word32
|
||||||
|
instance ToText Word16
|
||||||
|
instance FromText Word16
|
||||||
|
instance ToText Word8
|
||||||
|
instance FromText Word8
|
||||||
|
instance ToText Word
|
||||||
|
instance FromText Word
|
||||||
|
instance ToText Int64
|
||||||
|
instance FromText Int64
|
||||||
|
instance ToText Int32
|
||||||
|
instance FromText Int32
|
||||||
|
instance ToText Int16
|
||||||
|
instance FromText Int16
|
||||||
|
instance ToText Int8
|
||||||
|
instance FromText Int8
|
||||||
|
instance ToText Int
|
||||||
|
instance FromText Int
|
||||||
|
instance ToText Bool
|
||||||
|
instance FromText Bool
|
||||||
|
instance ToText String
|
||||||
|
instance FromText String
|
||||||
|
instance ToText Text
|
||||||
|
instance FromText Text
|
||||||
|
|
||||||
|
|
||||||
|
-- | This module lets you implement <a>Server</a>s for defined APIs. You'll
|
||||||
|
-- most likely just need <a>serve</a>.
|
||||||
|
module Servant.Server
|
||||||
|
|
||||||
|
-- | <a>serve</a> allows you to implement an API and produce a wai
|
||||||
|
-- <a>Application</a>.
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- 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
|
||||||
|
-- </pre>
|
||||||
|
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
|
||||||
|
|
||||||
|
-- | <pre>
|
||||||
|
-- > mempty = NotFound
|
||||||
|
-- >
|
||||||
|
-- > NotFound <a>mappend</a> x = x
|
||||||
|
-- > WrongMethod <a>mappend</a> InvalidBody = InvalidBody
|
||||||
|
-- > WrongMethod <a>mappend</a> _ = WrongMethod
|
||||||
|
-- > InvalidBody <a>mappend</a> _ = InvalidBody
|
||||||
|
-- </pre>
|
||||||
|
|
||||||
|
-- | A wrapper around <tt><a>Either</a> <a>RouteMismatch</a> a</tt>.
|
||||||
|
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 <a>Right</a>, it has precedence over everything else.
|
||||||
|
--
|
||||||
|
-- This in particular means that if we could get several <a>Right</a>s,
|
||||||
|
-- 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 <tt>("/" ++
|
||||||
|
-- path)</tt> (path being the first argument).
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- -- GET /hello/world
|
||||||
|
-- -- returning a JSON encoded World value
|
||||||
|
-- type MyApi = "hello" :> "world" :> Get World
|
||||||
|
-- </pre>
|
||||||
|
data (:>) (path :: k) a
|
||||||
|
(:>) :: Proxy path -> a -> (:>) a
|
||||||
|
|
||||||
|
-- | Make sure the incoming request starts with <tt>"/path"</tt>, strip it
|
||||||
|
-- and pass the rest of the request path to <tt>sublayout</tt>.
|
||||||
|
instance (KnownSymbol path, HasServer sublayout) => HasServer (path :> sublayout)
|
||||||
|
|
||||||
|
module Servant.API.Alternative
|
||||||
|
|
||||||
|
-- | Union of two APIs, first takes precedence in case of overlap.
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- type MyApi = "books" :> Get [Book] -- GET /books
|
||||||
|
-- :<|> "books" :> ReqBody Book :> Post Book -- POST /books
|
||||||
|
-- </pre>
|
||||||
|
data (:<|>) a b
|
||||||
|
(:<|>) :: a -> b -> (:<|>) a b
|
||||||
|
|
||||||
|
-- | A server for <tt>a <a>:<|></a> b</tt> first tries to match the
|
||||||
|
-- request again the route represented by <tt>a</tt> and if it fails
|
||||||
|
-- tries <tt>b</tt>. You must provide a request handler for each route.
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- type MyApi = "books" :> Get [Book] -- GET /books
|
||||||
|
-- :<|> "books" :> ReqBody Book :> Post Book -- POST /books
|
||||||
|
--
|
||||||
|
-- server :: Server MyApi
|
||||||
|
-- server = listAllBooks :<|> postBook
|
||||||
|
-- where listAllBooks = ...
|
||||||
|
-- postBook book = ...
|
||||||
|
-- </pre>
|
||||||
|
instance (HasServer a, HasServer b) => HasServer (a :<|> b)
|
||||||
|
|
||||||
|
module Servant.API.Capture
|
||||||
|
|
||||||
|
-- | Capture a value from the request path under a certain type <tt>a</tt>.
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- -- GET /books/:isbn
|
||||||
|
-- type MyApi = "books" :> Capture "isbn" Text :> Get Book
|
||||||
|
-- </pre>
|
||||||
|
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 <tt>sym</tt> query string parameter
|
||||||
|
-- and try to extract it as a value of type <tt>a</tt>.
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- -- /books?author=<author name>
|
||||||
|
-- type MyApi = "books" :> QueryParam "author" Text :> Get [Book]
|
||||||
|
-- </pre>
|
||||||
|
data QueryParam sym a
|
||||||
|
|
||||||
|
-- | If you use <tt><a>QueryParam</a> "author" Text</tt> 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
|
||||||
|
-- <tt><a>Maybe</a> <tt>Text</tt></tt>.
|
||||||
|
--
|
||||||
|
-- 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
|
||||||
|
-- <a>Maybe</a>, because it may not be there and servant would then hand
|
||||||
|
-- you <a>Nothing</a>.
|
||||||
|
--
|
||||||
|
-- You can control how it'll be converted from <tt>Text</tt> to your type
|
||||||
|
-- by simply providing an instance of <a>FromText</a> for your type.
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- 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...
|
||||||
|
-- </pre>
|
||||||
|
|
||||||
|
-- | Lookup the values associated to the <tt>sym</tt> query string
|
||||||
|
-- parameter and try to extract it as a value of type <tt>[a]</tt>. This
|
||||||
|
-- is typically meant to support query string parameters of the form
|
||||||
|
-- <tt>param[]=val1&param[]=val2</tt> and so on. Note that servant
|
||||||
|
-- doesn't actually require the <tt>[]</tt>s and will fetch the values
|
||||||
|
-- just fine with <tt>param=val1&param=val2</tt>, too.
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- -- /books?authors[]=<author1>&authors[]=<author2>&...
|
||||||
|
-- type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]
|
||||||
|
-- </pre>
|
||||||
|
data QueryParams sym a
|
||||||
|
|
||||||
|
-- | If you use <tt><a>QueryParams</a> "authors" Text</tt> 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
|
||||||
|
-- <tt>[<tt>Text</tt>]</tt>.
|
||||||
|
--
|
||||||
|
-- This lets servant worry about looking up 0 or more values in the query
|
||||||
|
-- string associated to <tt>authors</tt> and turning each of them into a
|
||||||
|
-- value of the type you specify.
|
||||||
|
--
|
||||||
|
-- You can control how the individual values are converted from
|
||||||
|
-- <tt>Text</tt> to your type by simply providing an instance of
|
||||||
|
-- <a>FromText</a> for your type.
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- 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...
|
||||||
|
-- </pre>
|
||||||
|
|
||||||
|
-- | Lookup a potentially value-less query string parameter with boolean
|
||||||
|
-- semantics. If the param <tt>sym</tt> is there without any value, or if
|
||||||
|
-- it's there with value "true" or "1", it's interpreted as <a>True</a>.
|
||||||
|
-- Otherwise, it's interpreted as <a>False</a>.
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- -- /books?published
|
||||||
|
-- type MyApi = "books" :> QueryFlag "published" :> Get [Book]
|
||||||
|
-- </pre>
|
||||||
|
data QueryFlag sym
|
||||||
|
|
||||||
|
-- | If you use <tt><a>QueryFlag</a> "published"</tt> 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 <a>Bool</a>.
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- 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...
|
||||||
|
-- </pre>
|
||||||
|
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 <tt>a</tt>.
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- -- POST /books
|
||||||
|
-- type MyApi = "books" :> ReqBody Book :> Post Book
|
||||||
|
-- </pre>
|
||||||
|
data ReqBody a
|
||||||
|
|
||||||
|
-- | If you use <a>ReqBody</a> 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 <a>ReqBody</a>. 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 <a>FromJSON</a> instance.
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- 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...
|
||||||
|
-- </pre>
|
||||||
|
instance (FromJSON a, HasServer sublayout) => HasServer (ReqBody a :> sublayout)
|
||||||
|
|
||||||
|
module Servant.API.Get
|
||||||
|
|
||||||
|
-- | Endpoint for simple GET requests. Serves the result as JSON.
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- type MyApi = "books" :> Get [Book]
|
||||||
|
-- </pre>
|
||||||
|
data Get a
|
||||||
|
|
||||||
|
-- | When implementing the handler for a <a>Get</a> endpoint, just like for
|
||||||
|
-- <a>Delete</a>, <a>Post</a> and <a>Put</a>, the handler code runs in
|
||||||
|
-- the <tt>EitherT (Int, String) IO</tt> monad, where the <a>Int</a>
|
||||||
|
-- represents the status code and the <a>String</a> a message, returned
|
||||||
|
-- in case of failure. You can quite handily use <a>left</a> to quickly
|
||||||
|
-- fail if some conditions are not met.
|
||||||
|
--
|
||||||
|
-- If successfully returning a value, we just require that its type has a
|
||||||
|
-- <a>ToJSON</a> 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 <a>RQBody</a> for that).
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- -- POST /books
|
||||||
|
-- -- with a JSON encoded Book as the request body
|
||||||
|
-- -- returning the just-created Book
|
||||||
|
-- type MyApi = "books" :> ReqBody Book :> Post Book
|
||||||
|
-- </pre>
|
||||||
|
data Post a
|
||||||
|
|
||||||
|
-- | When implementing the handler for a <a>Post</a> endpoint, just like
|
||||||
|
-- for <a>Delete</a>, <a>Get</a> and <a>Put</a>, the handler code runs in
|
||||||
|
-- the <tt>EitherT (Int, String) IO</tt> monad, where the <a>Int</a>
|
||||||
|
-- represents the status code and the <a>String</a> a message, returned
|
||||||
|
-- in case of failure. You can quite handily use <a>left</a> to quickly
|
||||||
|
-- fail if some conditions are not met.
|
||||||
|
--
|
||||||
|
-- If successfully returning a value, we just require that its type has a
|
||||||
|
-- <a>ToJSON</a> 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:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- -- DELETE /books/:isbn
|
||||||
|
-- type MyApi = "books" :> Capture "isbn" Text :> Delete
|
||||||
|
-- </pre>
|
||||||
|
data Delete
|
||||||
|
|
||||||
|
-- | If you have a <a>Delete</a> endpoint in your API, the handler for this
|
||||||
|
-- endpoint is meant to delete a resource.
|
||||||
|
--
|
||||||
|
-- The code of the handler will, just like for <a>Get</a>, <a>Post</a>
|
||||||
|
-- and <a>Put</a>, run in <tt>EitherT (Int, String) IO ()</tt>. The
|
||||||
|
-- <a>Int</a> represents the status code and the <a>String</a> a message
|
||||||
|
-- to be returned. You can use <a>left</a> 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 <tt>a</tt> is the type of the response body that's returned.
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- -- PUT /books/:isbn
|
||||||
|
-- -- with a Book as request body, returning the updated Book
|
||||||
|
-- type MyApi = "books" :> Capture "isbn" Text :> ReqBody Book :> Put Book
|
||||||
|
-- </pre>
|
||||||
|
data Put a
|
||||||
|
|
||||||
|
-- | When implementing the handler for a <a>Put</a> endpoint, just like for
|
||||||
|
-- <a>Delete</a>, <a>Get</a> and <a>Post</a>, the handler code runs in
|
||||||
|
-- the <tt>EitherT (Int, String) IO</tt> monad, where the <a>Int</a>
|
||||||
|
-- represents the status code and the <a>String</a> a message, returned
|
||||||
|
-- in case of failure. You can quite handily use <a>left</a> to quickly
|
||||||
|
-- fail if some conditions are not met.
|
||||||
|
--
|
||||||
|
-- If successfully returning a value, we just require that its type has a
|
||||||
|
-- <a>ToJSON</a> 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.
|
||||||
|
--
|
||||||
|
-- <a>sitemap</a> allows you to write your type in a very natural way:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- [sitemap|
|
||||||
|
-- PUT hello String -> ()
|
||||||
|
-- POST hello/p:Int String -> ()
|
||||||
|
-- GET hello/?name:String Int
|
||||||
|
-- |]
|
||||||
|
-- </pre>
|
||||||
|
--
|
||||||
|
-- Will generate:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- "hello" :> ReqBody String :> Put ()
|
||||||
|
-- :<|> "hello" :> Capture "p" Int :> ReqBody String :> Post ()
|
||||||
|
-- :<|> "hello" :> QueryParam "name" String :> Get Int
|
||||||
|
-- </pre>
|
||||||
|
--
|
||||||
|
-- Note the <tt>/</tt> before a <tt>QueryParam</tt>!
|
||||||
|
module Servant.QQ
|
||||||
|
|
||||||
|
-- | Finally-tagless encoding for our DSL. Keeping <tt>repr'</tt> and
|
||||||
|
-- <tt>repr</tt> distinct when writing functions with an <tt>ExpSYM</tt>
|
||||||
|
-- context ensures certain invariants (for instance, that there is only
|
||||||
|
-- one of <a>get</a>, <a>post</a>, <a>put</a>, and <a>delete</a> 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.
|
||||||
|
--
|
||||||
|
-- <ul>
|
||||||
|
-- <li><tt>...<i><a>var</a>:<a>type</a></i>...</tt> becomes a
|
||||||
|
-- capture</li>
|
||||||
|
-- <li><tt>.../?<a>var</a>:<a>type</a></tt> becomes a query
|
||||||
|
-- parameter</li>
|
||||||
|
-- <li><tt><a>method</a> ... <a>typ</a></tt> becomes a method returning
|
||||||
|
-- <tt><a>typ</a></tt></li>
|
||||||
|
-- <li><tt><a>method</a> ... <a>typ1</a> -> <a>typ2</a></tt> becomes a
|
||||||
|
-- method with request body of <tt><a>typ1</a></tt> and returning
|
||||||
|
-- <tt><a>typ2</a></tt></li>
|
||||||
|
-- </ul>
|
||||||
|
--
|
||||||
|
-- Comments are allowed, and have the standard Haskell format
|
||||||
|
--
|
||||||
|
-- <ul>
|
||||||
|
-- <li><tt>--</tt> for inline</li>
|
||||||
|
-- <li><tt>{- ... -}</tt> for block</li>
|
||||||
|
-- </ul>
|
||||||
|
sitemap :: QuasiQuoter
|
||||||
|
instance ExpSYM Type Type
|
||||||
|
|
||||||
|
|
||||||
|
-- | Type safe internal links.
|
||||||
|
--
|
||||||
|
-- Provides the function <a>mkLink</a>:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- type API = Proxy ("hello" :> Get Int
|
||||||
|
-- :<a>|</a> "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
|
||||||
|
-- </pre>
|
||||||
|
--
|
||||||
|
-- That is, <a>mkLink</a> takes two arguments, a link proxy and a
|
||||||
|
-- sitemap, and returns a <a>Link</a>, but only typechecks if the link
|
||||||
|
-- proxy is a valid link, and part of the sitemap.
|
||||||
|
--
|
||||||
|
-- <b>N.B.:</b> <a>mkLink</a> assumes a capture matches any string
|
||||||
|
-- (without slashes).
|
||||||
|
module Servant.Utils.Links
|
||||||
|
|
||||||
|
-- | The 'ValidLinkIn f s' constraint holds when <tt>s</tt> is an API that
|
||||||
|
-- contains <tt>f</tt>, and <tt>f</tt> 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 <a>Application</a>s.
|
||||||
|
--
|
||||||
|
-- The given <a>Application</a> will get the request as received by the
|
||||||
|
-- server, potentially with a modified (stripped) <a>pathInfo</a> if the
|
||||||
|
-- <a>Application</a> is being routed with <a>:></a>.
|
||||||
|
--
|
||||||
|
-- In addition to just letting you plug in your existing WAI
|
||||||
|
-- <a>Application</a>s, this can also be used with <a>serveDirectory</a>
|
||||||
|
-- to serve static files stored in a particular directory on your
|
||||||
|
-- filesystem, or to serve your API's documentation with
|
||||||
|
-- <a>serveDocumentation</a>.
|
||||||
|
data Raw
|
||||||
|
|
||||||
|
-- | Just pass the request to the underlying application and serve its
|
||||||
|
-- response.
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- type MyApi = "images" :> Raw
|
||||||
|
--
|
||||||
|
-- server :: Server MyApi
|
||||||
|
-- server = serveDirectory "/var/www/images"
|
||||||
|
-- </pre>
|
||||||
|
instance HasServer Raw
|
||||||
|
|
||||||
|
|
||||||
|
-- | This module defines a sever-side handler that lets you serve static
|
||||||
|
-- files.
|
||||||
|
--
|
||||||
|
-- <ul>
|
||||||
|
-- <li><a>serveDirectory</a> lets you serve anything that lives under a
|
||||||
|
-- particular directory on your filesystem.</li>
|
||||||
|
-- </ul>
|
||||||
|
module Servant.Utils.StaticFiles
|
||||||
|
|
||||||
|
-- | Serve anything under the specified directory as a <a>Raw</a> endpoint.
|
||||||
|
--
|
||||||
|
-- <pre>
|
||||||
|
-- type MyApi = "static" :> Raw
|
||||||
|
--
|
||||||
|
-- server :: Server MyApi
|
||||||
|
-- server = serveDirectory "/var/www"
|
||||||
|
-- </pre>
|
||||||
|
--
|
||||||
|
-- would capture any request to <tt>/static/<something></tt> and
|
||||||
|
-- look for <tt><something></tt> under <tt>/var/www</tt>.
|
||||||
|
--
|
||||||
|
-- It will do its best to guess the MIME type for that file, based on the
|
||||||
|
-- extension, and send an appropriate <i>Content-Type</i> 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 <i>/static/</i> prefix. In that
|
||||||
|
-- case, remember to put the <a>serveDirectory</a> handler in the last
|
||||||
|
-- position, because <i>servant</i> 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
|
50
src/Servant-API-Alternative.html
Normal file
50
src/Servant-API-Alternative.html
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant/API/Alternative.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
|
||||||
|
<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE TypeOperators #-}</span>
|
||||||
|
<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
|
||||||
|
<a name="line-4"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Alternative</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-5"></a>
|
||||||
|
<a name="line-6"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Monoid</span>
|
||||||
|
<a name="line-7"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
|
||||||
|
<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
|
||||||
|
<a name="line-9"></a>
|
||||||
|
<a name="line-10"></a><span class='hs-comment'>-- | Union of two APIs, first takes precedence in case of overlap.</span>
|
||||||
|
<a name="line-11"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-12"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-13"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-14"></a><span class='hs-comment'>-- > type MyApi = "books" :> Get [Book] -- GET /books</span>
|
||||||
|
<a name="line-15"></a><span class='hs-comment'>-- > :<|> "books" :> ReqBody Book :> Post Book -- POST /books</span>
|
||||||
|
<a name="line-16"></a><span class='hs-keyword'>data</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:<|></span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:<|></span> <span class='hs-varid'>b</span>
|
||||||
|
<a name="line-17"></a><span class='hs-keyword'>infixr</span> <span class='hs-num'>8</span> <span class='hs-conop'>:<|></span>
|
||||||
|
<a name="line-18"></a>
|
||||||
|
<a name="line-19"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- | A server for @a ':<|>' b@ first tries to match the request again the route</span>
|
||||||
|
<a name="line-20"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- represented by @a@ and if it fails tries @b@. You must provide a request</span>
|
||||||
|
<a name="line-21"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- handler for each route.</span>
|
||||||
|
<a name="line-22"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-23"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- > type MyApi = "books" :> Get [Book] -- GET /books</span>
|
||||||
|
<a name="line-24"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- > :<|> "books" :> ReqBody Book :> Post Book -- POST /books</span>
|
||||||
|
<a name="line-25"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- ></span>
|
||||||
|
<a name="line-26"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- > server :: Server MyApi</span>
|
||||||
|
<a name="line-27"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- > server = listAllBooks :<|> postBook</span>
|
||||||
|
<a name="line-28"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- > where listAllBooks = ...</span>
|
||||||
|
<a name="line-29"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- > postBook book = ...</span>
|
||||||
|
<a name="line-30"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>HasServer</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-conop'>:<|></span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-31"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-conop'>:<|></span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Server</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:<|></span> <span class='hs-conid'>Server</span> <span class='hs-varid'>b</span>
|
||||||
|
<a name="line-32"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-conop'>:<|></span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-33"></a> <span class='hs-varid'>route</span> <span class='hs-varid'>pa</span> <span class='hs-varid'>a</span> <span class='hs-varid'>request</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span> <span class='hs-varid'>mResponse</span> <span class='hs-keyglyph'>-></span>
|
||||||
|
<a name="line-34"></a> <span class='hs-keyword'>if</span> <span class='hs-varid'>isMismatch</span> <span class='hs-varid'>mResponse</span>
|
||||||
|
<a name="line-35"></a> <span class='hs-keyword'>then</span> <span class='hs-varid'>route</span> <span class='hs-varid'>pb</span> <span class='hs-varid'>b</span> <span class='hs-varid'>request</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>mResponse'</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>respond</span> <span class='hs-layout'>(</span><span class='hs-varid'>mResponse</span> <span class='hs-varop'><></span> <span class='hs-varid'>mResponse'</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-36"></a> <span class='hs-keyword'>else</span> <span class='hs-varid'>respond</span> <span class='hs-varid'>mResponse</span>
|
||||||
|
<a name="line-37"></a>
|
||||||
|
<a name="line-38"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>pa</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>a</span>
|
||||||
|
<a name="line-39"></a> <span class='hs-varid'>pb</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>b</span>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
71
src/Servant-API-Capture.html
Normal file
71
src/Servant-API-Capture.html
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant/API/Capture.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE PolyKinds #-}</span>
|
||||||
|
<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
|
||||||
|
<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE TypeOperators #-}</span>
|
||||||
|
<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE FlexibleContexts #-}</span>
|
||||||
|
<a name="line-5"></a><span class='hs-comment'>{-# LANGUAGE FlexibleInstances #-}</span>
|
||||||
|
<a name="line-6"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
|
||||||
|
<a name="line-7"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Capture</span> <span class='hs-layout'>(</span><span class='hs-conid'>Capture</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-8"></a>
|
||||||
|
<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
|
||||||
|
<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span>
|
||||||
|
<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>TypeLits</span>
|
||||||
|
<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
|
||||||
|
<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Sub</span>
|
||||||
|
<a name="line-14"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Common</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span>
|
||||||
|
<a name="line-15"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
|
||||||
|
<a name="line-16"></a>
|
||||||
|
<a name="line-17"></a><span class='hs-comment'>-- | Capture a value from the request path under a certain type @a@.</span>
|
||||||
|
<a name="line-18"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-19"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-20"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-21"></a><span class='hs-comment'>-- > -- GET /books/:isbn</span>
|
||||||
|
<a name="line-22"></a><span class='hs-comment'>-- > type MyApi = "books" :> Capture "isbn" Text :> Get Book</span>
|
||||||
|
<a name="line-23"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Capture</span> <span class='hs-varid'>sym</span> <span class='hs-varid'>a</span>
|
||||||
|
<a name="line-24"></a>
|
||||||
|
<a name="line-25"></a><a name="captured"></a><span class='hs-definition'>captured</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FromText</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=></span> <span class='hs-varid'>proxy</span> <span class='hs-layout'>(</span><span class='hs-conid'>Capture</span> <span class='hs-varid'>sym</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Text</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Maybe</span> <span class='hs-varid'>a</span>
|
||||||
|
<a name="line-26"></a><span class='hs-definition'>captured</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fromText</span>
|
||||||
|
<a name="line-27"></a>
|
||||||
|
<a name="line-28"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- | If you use 'Capture' in one of the endpoints for your API,</span>
|
||||||
|
<a name="line-29"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- this automatically requires your server-side handler to be a function</span>
|
||||||
|
<a name="line-30"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- that takes an argument of the type specified by the 'Capture'.</span>
|
||||||
|
<a name="line-31"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- This lets servant worry about getting it from the URL and turning</span>
|
||||||
|
<a name="line-32"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- it into a value of the type you specify.</span>
|
||||||
|
<a name="line-33"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-34"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- You can control how it'll be converted from 'Text' to your type</span>
|
||||||
|
<a name="line-35"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- by simply providing an instance of 'FromText' for your type.</span>
|
||||||
|
<a name="line-36"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-37"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-38"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-39"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > type MyApi = "books" :> Capture "isbn" Text :> Get Book</span>
|
||||||
|
<a name="line-40"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- ></span>
|
||||||
|
<a name="line-41"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > server :: Server MyApi</span>
|
||||||
|
<a name="line-42"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > server = getBook</span>
|
||||||
|
<a name="line-43"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > where getBook :: Text -> EitherT (Int, String) IO Book</span>
|
||||||
|
<a name="line-44"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > getBook isbn = ...</span>
|
||||||
|
<a name="line-45"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>KnownSymbol</span> <span class='hs-varid'>capture</span><span class='hs-layout'>,</span> <span class='hs-conid'>FromText</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-46"></a> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-conid'>Capture</span> <span class='hs-varid'>capture</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-47"></a>
|
||||||
|
<a name="line-48"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-conid'>Capture</span> <span class='hs-varid'>capture</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-49"></a> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Server</span> <span class='hs-varid'>sublayout</span>
|
||||||
|
<a name="line-50"></a>
|
||||||
|
<a name="line-51"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>subserver</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span> <span class='hs-keyword'>of</span>
|
||||||
|
<a name="line-52"></a> <span class='hs-layout'>(</span><span class='hs-varid'>first</span> <span class='hs-conop'>:</span> <span class='hs-varid'>rest</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-53"></a> <span class='hs-keyglyph'>-></span> <span class='hs-keyword'>case</span> <span class='hs-varid'>captured</span> <span class='hs-varid'>captureProxy</span> <span class='hs-varid'>first</span> <span class='hs-keyword'>of</span>
|
||||||
|
<a name="line-54"></a> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>NotFound</span>
|
||||||
|
<a name="line-55"></a> <span class='hs-conid'>Just</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>route</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>subserver</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-varid'>request</span><span class='hs-layout'>{</span>
|
||||||
|
<a name="line-56"></a> <span class='hs-varid'>pathInfo</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>rest</span>
|
||||||
|
<a name="line-57"></a> <span class='hs-layout'>}</span> <span class='hs-varid'>respond</span>
|
||||||
|
<a name="line-58"></a> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>NotFound</span>
|
||||||
|
<a name="line-59"></a>
|
||||||
|
<a name="line-60"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>captureProxy</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-layout'>(</span><span class='hs-conid'>Capture</span> <span class='hs-varid'>capture</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
59
src/Servant-API-Delete.html
Normal file
59
src/Servant-API-Delete.html
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant/API/Delete.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
|
||||||
|
<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE OverloadedStrings #-}</span>
|
||||||
|
<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
|
||||||
|
<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE DeriveDataTypeable #-}</span>
|
||||||
|
<a name="line-5"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Delete</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-6"></a>
|
||||||
|
<a name="line-7"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span><span class='hs-varop'>.</span><span class='hs-conid'>Trans</span><span class='hs-varop'>.</span><span class='hs-conid'>Either</span>
|
||||||
|
<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
|
||||||
|
<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>String</span><span class='hs-varop'>.</span><span class='hs-conid'>Conversions</span>
|
||||||
|
<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Typeable</span>
|
||||||
|
<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>HTTP</span><span class='hs-varop'>.</span><span class='hs-conid'>Types</span>
|
||||||
|
<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
|
||||||
|
<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
|
||||||
|
<a name="line-14"></a>
|
||||||
|
<a name="line-15"></a><a name="Delete"></a><span class='hs-comment'>-- | Combinator for DELETE requests.</span>
|
||||||
|
<a name="line-16"></a><a name="Delete"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-17"></a><a name="Delete"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-18"></a><a name="Delete"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-19"></a><a name="Delete"></a><span class='hs-comment'>-- > -- DELETE /books/:isbn</span>
|
||||||
|
<a name="line-20"></a><a name="Delete"></a><span class='hs-comment'>-- > type MyApi = "books" :> Capture "isbn" Text :> Delete</span>
|
||||||
|
<a name="line-21"></a><a name="Delete"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Delete</span>
|
||||||
|
<a name="line-22"></a> <span class='hs-keyword'>deriving</span> <span class='hs-conid'>Typeable</span>
|
||||||
|
<a name="line-23"></a>
|
||||||
|
<a name="line-24"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- | If you have a 'Delete' endpoint in your API,</span>
|
||||||
|
<a name="line-25"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- the handler for this endpoint is meant to delete</span>
|
||||||
|
<a name="line-26"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- a resource.</span>
|
||||||
|
<a name="line-27"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-28"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- The code of the handler will, just like</span>
|
||||||
|
<a name="line-29"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- for 'Servant.API.Get.Get', 'Servant.API.Post.Post' and</span>
|
||||||
|
<a name="line-30"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- 'Servant.API.Put.Put', run in @EitherT (Int, String) IO ()@.</span>
|
||||||
|
<a name="line-31"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- The 'Int' represents the status code and the 'String' a message</span>
|
||||||
|
<a name="line-32"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- to be returned. You can use 'Control.Monad.Trans.Either.left' to</span>
|
||||||
|
<a name="line-33"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- painlessly error out if the conditions for a successful deletion</span>
|
||||||
|
<a name="line-34"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- are not met.</span>
|
||||||
|
<a name="line-35"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>HasServer</span> <span class='hs-conid'>Delete</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-36"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-conid'>Delete</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>EitherT</span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-conid'>String</span><span class='hs-layout'>)</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>()</span>
|
||||||
|
<a name="line-37"></a>
|
||||||
|
<a name="line-38"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>action</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span>
|
||||||
|
<a name="line-39"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-layout'>(</span><span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span><span class='hs-layout'>)</span> <span class='hs-varop'>&&</span> <span class='hs-varid'>requestMethod</span> <span class='hs-varid'>request</span> <span class='hs-varop'>==</span> <span class='hs-varid'>methodDelete</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-40"></a> <span class='hs-varid'>e</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>runEitherT</span> <span class='hs-varid'>action</span>
|
||||||
|
<a name="line-41"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>succeedWith</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>e</span> <span class='hs-keyword'>of</span>
|
||||||
|
<a name="line-42"></a> <span class='hs-conid'>Right</span> <span class='hs-conid'>()</span> <span class='hs-keyglyph'>-></span>
|
||||||
|
<a name="line-43"></a> <span class='hs-varid'>responseLBS</span> <span class='hs-varid'>status204</span> <span class='hs-conid'>[]</span> <span class='hs-str'>""</span>
|
||||||
|
<a name="line-44"></a> <span class='hs-conid'>Left</span> <span class='hs-layout'>(</span><span class='hs-varid'>status</span><span class='hs-layout'>,</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span>
|
||||||
|
<a name="line-45"></a> <span class='hs-varid'>responseLBS</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkStatus</span> <span class='hs-varid'>status</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-conid'>[]</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-46"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-layout'>(</span><span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span><span class='hs-layout'>)</span> <span class='hs-varop'>&&</span> <span class='hs-varid'>requestMethod</span> <span class='hs-varid'>request</span> <span class='hs-varop'>/=</span> <span class='hs-varid'>methodDelete</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-47"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>WrongMethod</span>
|
||||||
|
<a name="line-48"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>NotFound</span>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
58
src/Servant-API-Get.html
Normal file
58
src/Servant-API-Get.html
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant/API/Get.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
|
||||||
|
<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE OverloadedStrings #-}</span>
|
||||||
|
<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
|
||||||
|
<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE DeriveDataTypeable #-}</span>
|
||||||
|
<a name="line-5"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Get</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-6"></a>
|
||||||
|
<a name="line-7"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span><span class='hs-varop'>.</span><span class='hs-conid'>Trans</span><span class='hs-varop'>.</span><span class='hs-conid'>Either</span>
|
||||||
|
<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Aeson</span>
|
||||||
|
<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
|
||||||
|
<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>String</span><span class='hs-varop'>.</span><span class='hs-conid'>Conversions</span>
|
||||||
|
<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Typeable</span>
|
||||||
|
<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>HTTP</span><span class='hs-varop'>.</span><span class='hs-conid'>Types</span>
|
||||||
|
<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
|
||||||
|
<a name="line-14"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
|
||||||
|
<a name="line-15"></a>
|
||||||
|
<a name="line-16"></a><a name="HasServer"></a><span class='hs-comment'>-- | Endpoint for simple GET requests. Serves the result as JSON.</span>
|
||||||
|
<a name="line-17"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-18"></a><a name="HasServer"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-19"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-20"></a><a name="HasServer"></a><span class='hs-comment'>-- > type MyApi = "books" :> Get [Book]</span>
|
||||||
|
<a name="line-21"></a><a name="HasServer"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Get</span> <span class='hs-varid'>a</span>
|
||||||
|
<a name="line-22"></a> <span class='hs-keyword'>deriving</span> <span class='hs-conid'>Typeable</span>
|
||||||
|
<a name="line-23"></a>
|
||||||
|
<a name="line-24"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- | When implementing the handler for a 'Get' endpoint,</span>
|
||||||
|
<a name="line-25"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- just like for 'Servant.API.Delete.Delete', 'Servant.API.Post.Post'</span>
|
||||||
|
<a name="line-26"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- and 'Servant.API.Put.Put', the handler code runs in the</span>
|
||||||
|
<a name="line-27"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- @EitherT (Int, String) IO@ monad, where the 'Int' represents</span>
|
||||||
|
<a name="line-28"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- the status code and the 'String' a message, returned in case of</span>
|
||||||
|
<a name="line-29"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- failure. You can quite handily use 'Control.Monad.Trans.EitherT.left'</span>
|
||||||
|
<a name="line-30"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- to quickly fail if some conditions are not met.</span>
|
||||||
|
<a name="line-31"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-32"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- If successfully returning a value, we just require that its type has</span>
|
||||||
|
<a name="line-33"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- a 'ToJSON' instance and servant takes care of encoding it for you,</span>
|
||||||
|
<a name="line-34"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- yielding status code 200 along the way.</span>
|
||||||
|
<a name="line-35"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToJSON</span> <span class='hs-varid'>result</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-conid'>Get</span> <span class='hs-varid'>result</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-36"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-conid'>Get</span> <span class='hs-varid'>result</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>EitherT</span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-conid'>String</span><span class='hs-layout'>)</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>result</span>
|
||||||
|
<a name="line-37"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>action</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span>
|
||||||
|
<a name="line-38"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-layout'>(</span><span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span><span class='hs-layout'>)</span> <span class='hs-varop'>&&</span> <span class='hs-varid'>requestMethod</span> <span class='hs-varid'>request</span> <span class='hs-varop'>==</span> <span class='hs-varid'>methodGet</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-39"></a> <span class='hs-varid'>e</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>runEitherT</span> <span class='hs-varid'>action</span>
|
||||||
|
<a name="line-40"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>.</span> <span class='hs-varid'>succeedWith</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>e</span> <span class='hs-keyword'>of</span>
|
||||||
|
<a name="line-41"></a> <span class='hs-conid'>Right</span> <span class='hs-varid'>output</span> <span class='hs-keyglyph'>-></span>
|
||||||
|
<a name="line-42"></a> <span class='hs-varid'>responseLBS</span> <span class='hs-varid'>ok200</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-str'>"Content-Type"</span><span class='hs-layout'>,</span> <span class='hs-str'>"application/json"</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <span class='hs-layout'>(</span><span class='hs-varid'>encode</span> <span class='hs-varid'>output</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-43"></a> <span class='hs-conid'>Left</span> <span class='hs-layout'>(</span><span class='hs-varid'>status</span><span class='hs-layout'>,</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span>
|
||||||
|
<a name="line-44"></a> <span class='hs-varid'>responseLBS</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkStatus</span> <span class='hs-varid'>status</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-conid'>[]</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-45"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-layout'>(</span><span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span><span class='hs-layout'>)</span> <span class='hs-varop'>&&</span> <span class='hs-varid'>requestMethod</span> <span class='hs-varid'>request</span> <span class='hs-varop'>/=</span> <span class='hs-varid'>methodGet</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-46"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>WrongMethod</span>
|
||||||
|
<a name="line-47"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>NotFound</span>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
64
src/Servant-API-Post.html
Normal file
64
src/Servant-API-Post.html
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant/API/Post.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
|
||||||
|
<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE OverloadedStrings #-}</span>
|
||||||
|
<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
|
||||||
|
<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE DeriveDataTypeable #-}</span>
|
||||||
|
<a name="line-5"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Post</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-6"></a>
|
||||||
|
<a name="line-7"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span><span class='hs-varop'>.</span><span class='hs-conid'>Trans</span><span class='hs-varop'>.</span><span class='hs-conid'>Either</span>
|
||||||
|
<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Aeson</span>
|
||||||
|
<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
|
||||||
|
<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>String</span><span class='hs-varop'>.</span><span class='hs-conid'>Conversions</span>
|
||||||
|
<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Typeable</span>
|
||||||
|
<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>HTTP</span><span class='hs-varop'>.</span><span class='hs-conid'>Types</span>
|
||||||
|
<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
|
||||||
|
<a name="line-14"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
|
||||||
|
<a name="line-15"></a>
|
||||||
|
<a name="line-16"></a><a name="HasServer"></a><span class='hs-comment'>-- | Endpoint for POST requests. The type variable represents the type of the</span>
|
||||||
|
<a name="line-17"></a><a name="HasServer"></a><span class='hs-comment'>-- response body (not the request body, use 'Servant.API.RQBody.RQBody' for</span>
|
||||||
|
<a name="line-18"></a><a name="HasServer"></a><span class='hs-comment'>-- that).</span>
|
||||||
|
<a name="line-19"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-20"></a><a name="HasServer"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-21"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-22"></a><a name="HasServer"></a><span class='hs-comment'>-- > -- POST /books</span>
|
||||||
|
<a name="line-23"></a><a name="HasServer"></a><span class='hs-comment'>-- > -- with a JSON encoded Book as the request body</span>
|
||||||
|
<a name="line-24"></a><a name="HasServer"></a><span class='hs-comment'>-- > -- returning the just-created Book</span>
|
||||||
|
<a name="line-25"></a><a name="HasServer"></a><span class='hs-comment'>-- > type MyApi = "books" :> ReqBody Book :> Post Book</span>
|
||||||
|
<a name="line-26"></a><a name="HasServer"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Post</span> <span class='hs-varid'>a</span>
|
||||||
|
<a name="line-27"></a> <span class='hs-keyword'>deriving</span> <span class='hs-conid'>Typeable</span>
|
||||||
|
<a name="line-28"></a>
|
||||||
|
<a name="line-29"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- | When implementing the handler for a 'Post' endpoint,</span>
|
||||||
|
<a name="line-30"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- just like for 'Servant.API.Delete.Delete', 'Servant.API.Get.Get'</span>
|
||||||
|
<a name="line-31"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- and 'Servant.API.Put.Put', the handler code runs in the</span>
|
||||||
|
<a name="line-32"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- @EitherT (Int, String) IO@ monad, where the 'Int' represents</span>
|
||||||
|
<a name="line-33"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- the status code and the 'String' a message, returned in case of</span>
|
||||||
|
<a name="line-34"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- failure. You can quite handily use 'Control.Monad.Trans.EitherT.left'</span>
|
||||||
|
<a name="line-35"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- to quickly fail if some conditions are not met.</span>
|
||||||
|
<a name="line-36"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-37"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- If successfully returning a value, we just require that its type has</span>
|
||||||
|
<a name="line-38"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- a 'ToJSON' instance and servant takes care of encoding it for you,</span>
|
||||||
|
<a name="line-39"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- yielding status code 201 along the way.</span>
|
||||||
|
<a name="line-40"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToJSON</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-conid'>Post</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-41"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-conid'>Post</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>EitherT</span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-conid'>String</span><span class='hs-layout'>)</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>a</span>
|
||||||
|
<a name="line-42"></a>
|
||||||
|
<a name="line-43"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>action</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span>
|
||||||
|
<a name="line-44"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-layout'>(</span><span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span><span class='hs-layout'>)</span> <span class='hs-varop'>&&</span> <span class='hs-varid'>requestMethod</span> <span class='hs-varid'>request</span> <span class='hs-varop'>==</span> <span class='hs-varid'>methodPost</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-45"></a> <span class='hs-varid'>e</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>runEitherT</span> <span class='hs-varid'>action</span>
|
||||||
|
<a name="line-46"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>.</span> <span class='hs-varid'>succeedWith</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>e</span> <span class='hs-keyword'>of</span>
|
||||||
|
<a name="line-47"></a> <span class='hs-conid'>Right</span> <span class='hs-varid'>out</span> <span class='hs-keyglyph'>-></span>
|
||||||
|
<a name="line-48"></a> <span class='hs-varid'>responseLBS</span> <span class='hs-varid'>status201</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-str'>"Content-Type"</span><span class='hs-layout'>,</span> <span class='hs-str'>"application/json"</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <span class='hs-layout'>(</span><span class='hs-varid'>encode</span> <span class='hs-varid'>out</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-49"></a> <span class='hs-conid'>Left</span> <span class='hs-layout'>(</span><span class='hs-varid'>status</span><span class='hs-layout'>,</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span>
|
||||||
|
<a name="line-50"></a> <span class='hs-varid'>responseLBS</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkStatus</span> <span class='hs-varid'>status</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-conid'>[]</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-51"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-layout'>(</span><span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span><span class='hs-layout'>)</span> <span class='hs-varop'>&&</span> <span class='hs-varid'>requestMethod</span> <span class='hs-varid'>request</span> <span class='hs-varop'>/=</span> <span class='hs-varid'>methodPost</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-52"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>WrongMethod</span>
|
||||||
|
<a name="line-53"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>NotFound</span>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
63
src/Servant-API-Put.html
Normal file
63
src/Servant-API-Put.html
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant/API/Put.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
|
||||||
|
<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE OverloadedStrings #-}</span>
|
||||||
|
<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
|
||||||
|
<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE DeriveDataTypeable #-}</span>
|
||||||
|
<a name="line-5"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Put</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-6"></a>
|
||||||
|
<a name="line-7"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span><span class='hs-varop'>.</span><span class='hs-conid'>Trans</span><span class='hs-varop'>.</span><span class='hs-conid'>Either</span>
|
||||||
|
<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Aeson</span>
|
||||||
|
<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
|
||||||
|
<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>String</span><span class='hs-varop'>.</span><span class='hs-conid'>Conversions</span>
|
||||||
|
<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Typeable</span>
|
||||||
|
<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>HTTP</span><span class='hs-varop'>.</span><span class='hs-conid'>Types</span>
|
||||||
|
<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
|
||||||
|
<a name="line-14"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
|
||||||
|
<a name="line-15"></a>
|
||||||
|
<a name="line-16"></a><a name="HasServer"></a><span class='hs-comment'>-- | Endpoint for PUT requests, usually used to update a ressource.</span>
|
||||||
|
<a name="line-17"></a><a name="HasServer"></a><span class='hs-comment'>-- The type @a@ is the type of the response body that's returned.</span>
|
||||||
|
<a name="line-18"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-19"></a><a name="HasServer"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-20"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-21"></a><a name="HasServer"></a><span class='hs-comment'>-- > -- PUT /books/:isbn</span>
|
||||||
|
<a name="line-22"></a><a name="HasServer"></a><span class='hs-comment'>-- > -- with a Book as request body, returning the updated Book</span>
|
||||||
|
<a name="line-23"></a><a name="HasServer"></a><span class='hs-comment'>-- > type MyApi = "books" :> Capture "isbn" Text :> ReqBody Book :> Put Book</span>
|
||||||
|
<a name="line-24"></a><a name="HasServer"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Put</span> <span class='hs-varid'>a</span>
|
||||||
|
<a name="line-25"></a> <span class='hs-keyword'>deriving</span> <span class='hs-conid'>Typeable</span>
|
||||||
|
<a name="line-26"></a>
|
||||||
|
<a name="line-27"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- | When implementing the handler for a 'Put' endpoint,</span>
|
||||||
|
<a name="line-28"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- just like for 'Servant.API.Delete.Delete', 'Servant.API.Get.Get'</span>
|
||||||
|
<a name="line-29"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- and 'Servant.API.Post.Post', the handler code runs in the</span>
|
||||||
|
<a name="line-30"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- @EitherT (Int, String) IO@ monad, where the 'Int' represents</span>
|
||||||
|
<a name="line-31"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- the status code and the 'String' a message, returned in case of</span>
|
||||||
|
<a name="line-32"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- failure. You can quite handily use 'Control.Monad.Trans.EitherT.left'</span>
|
||||||
|
<a name="line-33"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- to quickly fail if some conditions are not met.</span>
|
||||||
|
<a name="line-34"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-35"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- If successfully returning a value, we just require that its type has</span>
|
||||||
|
<a name="line-36"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- a 'ToJSON' instance and servant takes care of encoding it for you,</span>
|
||||||
|
<a name="line-37"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- yielding status code 200 along the way.</span>
|
||||||
|
<a name="line-38"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToJSON</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-conid'>Put</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-39"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-conid'>Put</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>EitherT</span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-conid'>String</span><span class='hs-layout'>)</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>a</span>
|
||||||
|
<a name="line-40"></a>
|
||||||
|
<a name="line-41"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>action</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span>
|
||||||
|
<a name="line-42"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-layout'>(</span><span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span><span class='hs-layout'>)</span> <span class='hs-varop'>&&</span> <span class='hs-varid'>requestMethod</span> <span class='hs-varid'>request</span> <span class='hs-varop'>==</span> <span class='hs-varid'>methodPut</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-43"></a> <span class='hs-varid'>e</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>runEitherT</span> <span class='hs-varid'>action</span>
|
||||||
|
<a name="line-44"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>.</span> <span class='hs-varid'>succeedWith</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>e</span> <span class='hs-keyword'>of</span>
|
||||||
|
<a name="line-45"></a> <span class='hs-conid'>Right</span> <span class='hs-varid'>out</span> <span class='hs-keyglyph'>-></span>
|
||||||
|
<a name="line-46"></a> <span class='hs-varid'>responseLBS</span> <span class='hs-varid'>ok200</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-str'>"Content-Type"</span><span class='hs-layout'>,</span> <span class='hs-str'>"application/json"</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <span class='hs-layout'>(</span><span class='hs-varid'>encode</span> <span class='hs-varid'>out</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-47"></a> <span class='hs-conid'>Left</span> <span class='hs-layout'>(</span><span class='hs-varid'>status</span><span class='hs-layout'>,</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span>
|
||||||
|
<a name="line-48"></a> <span class='hs-varid'>responseLBS</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkStatus</span> <span class='hs-varid'>status</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-conid'>[]</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-49"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-layout'>(</span><span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span><span class='hs-layout'>)</span> <span class='hs-varop'>&&</span> <span class='hs-varid'>requestMethod</span> <span class='hs-varid'>request</span> <span class='hs-varop'>/=</span> <span class='hs-varid'>methodPut</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-50"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>WrongMethod</span>
|
||||||
|
<a name="line-51"></a>
|
||||||
|
<a name="line-52"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>NotFound</span>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
173
src/Servant-API-QueryParam.html
Normal file
173
src/Servant-API-QueryParam.html
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant/API/QueryParam.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE PolyKinds #-}</span>
|
||||||
|
<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
|
||||||
|
<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE TypeOperators #-}</span>
|
||||||
|
<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE FlexibleContexts #-}</span>
|
||||||
|
<a name="line-5"></a><span class='hs-comment'>{-# LANGUAGE FlexibleInstances #-}</span>
|
||||||
|
<a name="line-6"></a><span class='hs-comment'>{-# LANGUAGE OverloadedStrings #-}</span>
|
||||||
|
<a name="line-7"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
|
||||||
|
<a name="line-8"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>QueryParam</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-9"></a>
|
||||||
|
<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Maybe</span>
|
||||||
|
<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
|
||||||
|
<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>String</span><span class='hs-varop'>.</span><span class='hs-conid'>Conversions</span>
|
||||||
|
<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>TypeLits</span>
|
||||||
|
<a name="line-14"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>HTTP</span><span class='hs-varop'>.</span><span class='hs-conid'>Types</span>
|
||||||
|
<a name="line-15"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
|
||||||
|
<a name="line-16"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Sub</span>
|
||||||
|
<a name="line-17"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Common</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span>
|
||||||
|
<a name="line-18"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
|
||||||
|
<a name="line-19"></a>
|
||||||
|
<a name="line-20"></a><a name="HasServer"></a><span class='hs-comment'>-- | Lookup the value associated to the @sym@ query string parameter</span>
|
||||||
|
<a name="line-21"></a><a name="HasServer"></a><span class='hs-comment'>-- and try to extract it as a value of type @a@.</span>
|
||||||
|
<a name="line-22"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-23"></a><a name="HasServer"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-24"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-25"></a><a name="HasServer"></a><span class='hs-comment'>-- > -- /books?author=<author name></span>
|
||||||
|
<a name="line-26"></a><a name="HasServer"></a><span class='hs-comment'>-- > type MyApi = "books" :> QueryParam "author" Text :> Get [Book]</span>
|
||||||
|
<a name="line-27"></a><a name="HasServer"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>QueryParam</span> <span class='hs-varid'>sym</span> <span class='hs-varid'>a</span>
|
||||||
|
<a name="line-28"></a>
|
||||||
|
<a name="line-29"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- | If you use @'QueryParam' "author" Text@ in one of the endpoints for your API,</span>
|
||||||
|
<a name="line-30"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- this automatically requires your server-side handler to be a function</span>
|
||||||
|
<a name="line-31"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- that takes an argument of type @'Maybe' 'Text'@.</span>
|
||||||
|
<a name="line-32"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-33"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- This lets servant worry about looking it up in the query string</span>
|
||||||
|
<a name="line-34"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- and turning it into a value of the type you specify, enclosed</span>
|
||||||
|
<a name="line-35"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- in 'Maybe', because it may not be there and servant would then</span>
|
||||||
|
<a name="line-36"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- hand you 'Nothing'.</span>
|
||||||
|
<a name="line-37"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-38"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- You can control how it'll be converted from 'Text' to your type</span>
|
||||||
|
<a name="line-39"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- by simply providing an instance of 'FromText' for your type.</span>
|
||||||
|
<a name="line-40"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-41"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-42"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-43"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > type MyApi = "books" :> QueryParam "author" Text :> Get [Book]</span>
|
||||||
|
<a name="line-44"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- ></span>
|
||||||
|
<a name="line-45"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > server :: Server MyApi</span>
|
||||||
|
<a name="line-46"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > server = getBooksBy</span>
|
||||||
|
<a name="line-47"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > where getBooksBy :: Maybe Text -> EitherT (Int, String) IO [Book]</span>
|
||||||
|
<a name="line-48"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > getBooksBy Nothing = ...return all books...</span>
|
||||||
|
<a name="line-49"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > getBooksBy (Just author) = ...return books by the given author...</span>
|
||||||
|
<a name="line-50"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>KnownSymbol</span> <span class='hs-varid'>sym</span><span class='hs-layout'>,</span> <span class='hs-conid'>FromText</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-51"></a> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-conid'>QueryParam</span> <span class='hs-varid'>sym</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-52"></a>
|
||||||
|
<a name="line-53"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-conid'>QueryParam</span> <span class='hs-varid'>sym</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-54"></a> <span class='hs-conid'>Maybe</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Server</span> <span class='hs-varid'>sublayout</span>
|
||||||
|
<a name="line-55"></a>
|
||||||
|
<a name="line-56"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>subserver</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-57"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>querytext</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>parseQueryText</span> <span class='hs-varop'>$</span> <span class='hs-varid'>rawQueryString</span> <span class='hs-varid'>request</span>
|
||||||
|
<a name="line-58"></a> <span class='hs-varid'>param</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-59"></a> <span class='hs-keyword'>case</span> <span class='hs-varid'>lookup</span> <span class='hs-varid'>paramname</span> <span class='hs-varid'>querytext</span> <span class='hs-keyword'>of</span>
|
||||||
|
<a name="line-60"></a> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Nothing</span> <span class='hs-comment'>-- param absent from the query string</span>
|
||||||
|
<a name="line-61"></a> <span class='hs-conid'>Just</span> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Nothing</span> <span class='hs-comment'>-- param present with no value -> Nothing</span>
|
||||||
|
<a name="line-62"></a> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>fromText</span> <span class='hs-varid'>v</span> <span class='hs-comment'>-- if present, we try to convert to</span>
|
||||||
|
<a name="line-63"></a> <span class='hs-comment'>-- the right type</span>
|
||||||
|
<a name="line-64"></a>
|
||||||
|
<a name="line-65"></a> <span class='hs-varid'>route</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>subserver</span> <span class='hs-varid'>param</span><span class='hs-layout'>)</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span>
|
||||||
|
<a name="line-66"></a>
|
||||||
|
<a name="line-67"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>paramname</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>$</span> <span class='hs-varid'>symbolVal</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sym</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-68"></a>
|
||||||
|
<a name="line-69"></a><a name="HasServer"></a><span class='hs-comment'>-- | Lookup the values associated to the @sym@ query string parameter</span>
|
||||||
|
<a name="line-70"></a><a name="HasServer"></a><span class='hs-comment'>-- and try to extract it as a value of type @[a]@. This is typically</span>
|
||||||
|
<a name="line-71"></a><a name="HasServer"></a><span class='hs-comment'>-- meant to support query string parameters of the form</span>
|
||||||
|
<a name="line-72"></a><a name="HasServer"></a><span class='hs-comment'>-- @param[]=val1&param[]=val2@ and so on. Note that servant doesn't actually</span>
|
||||||
|
<a name="line-73"></a><a name="HasServer"></a><span class='hs-comment'>-- require the @[]@s and will fetch the values just fine with</span>
|
||||||
|
<a name="line-74"></a><a name="HasServer"></a><span class='hs-comment'>-- @param=val1&param=val2@, too.</span>
|
||||||
|
<a name="line-75"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-76"></a><a name="HasServer"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-77"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-78"></a><a name="HasServer"></a><span class='hs-comment'>-- > -- /books?authors[]=<author1>&authors[]=<author2>&...</span>
|
||||||
|
<a name="line-79"></a><a name="HasServer"></a><span class='hs-comment'>-- > type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]</span>
|
||||||
|
<a name="line-80"></a><a name="HasServer"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>QueryParams</span> <span class='hs-varid'>sym</span> <span class='hs-varid'>a</span>
|
||||||
|
<a name="line-81"></a>
|
||||||
|
<a name="line-82"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- | If you use @'QueryParams' "authors" Text@ in one of the endpoints for your API,</span>
|
||||||
|
<a name="line-83"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- this automatically requires your server-side handler to be a function</span>
|
||||||
|
<a name="line-84"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- that takes an argument of type @['Text']@.</span>
|
||||||
|
<a name="line-85"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-86"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- This lets servant worry about looking up 0 or more values in the query string</span>
|
||||||
|
<a name="line-87"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- associated to @authors@ and turning each of them into a value of</span>
|
||||||
|
<a name="line-88"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- the type you specify.</span>
|
||||||
|
<a name="line-89"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-90"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- You can control how the individual values are converted from 'Text' to your type</span>
|
||||||
|
<a name="line-91"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- by simply providing an instance of 'FromText' for your type.</span>
|
||||||
|
<a name="line-92"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-93"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-94"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-95"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]</span>
|
||||||
|
<a name="line-96"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- ></span>
|
||||||
|
<a name="line-97"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > server :: Server MyApi</span>
|
||||||
|
<a name="line-98"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > server = getBooksBy</span>
|
||||||
|
<a name="line-99"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > where getBooksBy :: [Text] -> EitherT (Int, String) IO [Book]</span>
|
||||||
|
<a name="line-100"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > getBooksBy authors = ...return all books by these authors...</span>
|
||||||
|
<a name="line-101"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>KnownSymbol</span> <span class='hs-varid'>sym</span><span class='hs-layout'>,</span> <span class='hs-conid'>FromText</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-102"></a> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-conid'>QueryParams</span> <span class='hs-varid'>sym</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-103"></a>
|
||||||
|
<a name="line-104"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-conid'>QueryParams</span> <span class='hs-varid'>sym</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-105"></a> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Server</span> <span class='hs-varid'>sublayout</span>
|
||||||
|
<a name="line-106"></a>
|
||||||
|
<a name="line-107"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>subserver</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-108"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>querytext</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>parseQueryText</span> <span class='hs-varop'>$</span> <span class='hs-varid'>rawQueryString</span> <span class='hs-varid'>request</span>
|
||||||
|
<a name="line-109"></a> <span class='hs-comment'>-- if sym is "foo", we look for query string parameters</span>
|
||||||
|
<a name="line-110"></a> <span class='hs-comment'>-- named "foo" or "foo[]" and call fromText on the</span>
|
||||||
|
<a name="line-111"></a> <span class='hs-comment'>-- corresponding values</span>
|
||||||
|
<a name="line-112"></a> <span class='hs-varid'>parameters</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>filter</span> <span class='hs-varid'>looksLikeParam</span> <span class='hs-varid'>querytext</span>
|
||||||
|
<a name="line-113"></a> <span class='hs-varid'>values</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>catMaybes</span> <span class='hs-varop'>$</span> <span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-varid'>convert</span> <span class='hs-varop'>.</span> <span class='hs-varid'>snd</span><span class='hs-layout'>)</span> <span class='hs-varid'>parameters</span>
|
||||||
|
<a name="line-114"></a>
|
||||||
|
<a name="line-115"></a> <span class='hs-varid'>route</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>subserver</span> <span class='hs-varid'>values</span><span class='hs-layout'>)</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span>
|
||||||
|
<a name="line-116"></a>
|
||||||
|
<a name="line-117"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>paramname</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>$</span> <span class='hs-varid'>symbolVal</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sym</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-118"></a> <span class='hs-varid'>looksLikeParam</span> <span class='hs-layout'>(</span><span class='hs-varid'>name</span><span class='hs-layout'>,</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>name</span> <span class='hs-varop'>==</span> <span class='hs-varid'>paramname</span> <span class='hs-varop'>||</span> <span class='hs-varid'>name</span> <span class='hs-varop'>==</span> <span class='hs-layout'>(</span><span class='hs-varid'>paramname</span> <span class='hs-varop'><></span> <span class='hs-str'>"[]"</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-119"></a> <span class='hs-varid'>convert</span> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
|
||||||
|
<a name="line-120"></a> <span class='hs-varid'>convert</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fromText</span> <span class='hs-varid'>v</span>
|
||||||
|
<a name="line-121"></a>
|
||||||
|
<a name="line-122"></a><a name="HasServer"></a><span class='hs-comment'>-- | Lookup a potentially value-less query string parameter</span>
|
||||||
|
<a name="line-123"></a><a name="HasServer"></a><span class='hs-comment'>-- with boolean semantics. If the param @sym@ is there without any value,</span>
|
||||||
|
<a name="line-124"></a><a name="HasServer"></a><span class='hs-comment'>-- or if it's there with value "true" or "1", it's interpreted as 'True'.</span>
|
||||||
|
<a name="line-125"></a><a name="HasServer"></a><span class='hs-comment'>-- Otherwise, it's interpreted as 'False'.</span>
|
||||||
|
<a name="line-126"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-127"></a><a name="HasServer"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-128"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-129"></a><a name="HasServer"></a><span class='hs-comment'>-- > -- /books?published</span>
|
||||||
|
<a name="line-130"></a><a name="HasServer"></a><span class='hs-comment'>-- > type MyApi = "books" :> QueryFlag "published" :> Get [Book]</span>
|
||||||
|
<a name="line-131"></a><a name="HasServer"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>QueryFlag</span> <span class='hs-varid'>sym</span>
|
||||||
|
<a name="line-132"></a>
|
||||||
|
<a name="line-133"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- | If you use @'QueryFlag' "published"@ in one of the endpoints for your API,</span>
|
||||||
|
<a name="line-134"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- this automatically requires your server-side handler to be a function</span>
|
||||||
|
<a name="line-135"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- that takes an argument of type 'Bool'.</span>
|
||||||
|
<a name="line-136"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-137"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-138"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-139"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > type MyApi = "books" :> QueryFlag "published" :> Get [Book]</span>
|
||||||
|
<a name="line-140"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- ></span>
|
||||||
|
<a name="line-141"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > server :: Server MyApi</span>
|
||||||
|
<a name="line-142"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > server = getBooks</span>
|
||||||
|
<a name="line-143"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > where getBooks :: Bool -> EitherT (Int, String) IO [Book]</span>
|
||||||
|
<a name="line-144"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument...</span>
|
||||||
|
<a name="line-145"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>KnownSymbol</span> <span class='hs-varid'>sym</span><span class='hs-layout'>,</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-146"></a> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-conid'>QueryFlag</span> <span class='hs-varid'>sym</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-147"></a>
|
||||||
|
<a name="line-148"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-conid'>QueryFlag</span> <span class='hs-varid'>sym</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-149"></a> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Server</span> <span class='hs-varid'>sublayout</span>
|
||||||
|
<a name="line-150"></a>
|
||||||
|
<a name="line-151"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>subserver</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-152"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>querytext</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>parseQueryText</span> <span class='hs-varop'>$</span> <span class='hs-varid'>rawQueryString</span> <span class='hs-varid'>request</span>
|
||||||
|
<a name="line-153"></a> <span class='hs-varid'>param</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>lookup</span> <span class='hs-varid'>paramname</span> <span class='hs-varid'>querytext</span> <span class='hs-keyword'>of</span>
|
||||||
|
<a name="line-154"></a> <span class='hs-conid'>Just</span> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>True</span> <span class='hs-comment'>-- param is there, with no value</span>
|
||||||
|
<a name="line-155"></a> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>examine</span> <span class='hs-varid'>v</span> <span class='hs-comment'>-- param with a value</span>
|
||||||
|
<a name="line-156"></a> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>False</span> <span class='hs-comment'>-- param not in the query string</span>
|
||||||
|
<a name="line-157"></a>
|
||||||
|
<a name="line-158"></a> <span class='hs-varid'>route</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>subserver</span> <span class='hs-varid'>param</span><span class='hs-layout'>)</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span>
|
||||||
|
<a name="line-159"></a>
|
||||||
|
<a name="line-160"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>paramname</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>$</span> <span class='hs-varid'>symbolVal</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sym</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-161"></a> <span class='hs-varid'>examine</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>v</span> <span class='hs-varop'>==</span> <span class='hs-str'>"true"</span> <span class='hs-varop'>||</span> <span class='hs-varid'>v</span> <span class='hs-varop'>==</span> <span class='hs-str'>"1"</span> <span class='hs-varop'>||</span> <span class='hs-varid'>v</span> <span class='hs-varop'>==</span> <span class='hs-str'>""</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
|
||||||
|
<a name="line-162"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
43
src/Servant-API-Raw.html
Normal file
43
src/Servant-API-Raw.html
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant/API/Raw.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE InstanceSigs #-}</span>
|
||||||
|
<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE OverloadedStrings #-}</span>
|
||||||
|
<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
|
||||||
|
<a name="line-4"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Raw</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-5"></a>
|
||||||
|
<a name="line-6"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
|
||||||
|
<a name="line-7"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
|
||||||
|
<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
|
||||||
|
<a name="line-9"></a>
|
||||||
|
<a name="line-10"></a><a name="Raw"></a><span class='hs-comment'>-- | Endpoint for plugging in your own Wai 'Application's.</span>
|
||||||
|
<a name="line-11"></a><a name="Raw"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-12"></a><a name="Raw"></a><span class='hs-comment'>-- The given 'Application' will get the request as received by the server, potentially with</span>
|
||||||
|
<a name="line-13"></a><a name="Raw"></a><span class='hs-comment'>-- a modified (stripped) 'pathInfo' if the 'Application' is being routed with 'Servant.API.Sub.:>'.</span>
|
||||||
|
<a name="line-14"></a><a name="Raw"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-15"></a><a name="Raw"></a><span class='hs-comment'>-- In addition to just letting you plug in your existing WAI 'Application's,</span>
|
||||||
|
<a name="line-16"></a><a name="Raw"></a><span class='hs-comment'>-- this can also be used with 'Servant.Utils.StaticFiles.serveDirectory' to serve</span>
|
||||||
|
<a name="line-17"></a><a name="Raw"></a><span class='hs-comment'>-- static files stored in a particular directory on your filesystem, or to serve</span>
|
||||||
|
<a name="line-18"></a><a name="Raw"></a><span class='hs-comment'>-- your API's documentation with 'Servant.Utils.StaticFiles.serveDocumentation'.</span>
|
||||||
|
<a name="line-19"></a><a name="Raw"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Raw</span>
|
||||||
|
<a name="line-20"></a>
|
||||||
|
<a name="line-21"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-comment'>-- | Just pass the request to the underlying application and serve its response.</span>
|
||||||
|
<a name="line-22"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-23"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-24"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-25"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-comment'>-- > type MyApi = "images" :> Raw</span>
|
||||||
|
<a name="line-26"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-comment'>-- ></span>
|
||||||
|
<a name="line-27"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-comment'>-- > server :: Server MyApi</span>
|
||||||
|
<a name="line-28"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-comment'>-- > server = serveDirectory "/var/www/images"</span>
|
||||||
|
<a name="line-29"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>HasServer</span> <span class='hs-conid'>Raw</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-30"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-conid'>Raw</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Application</span>
|
||||||
|
<a name="line-31"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>rawApplication</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-32"></a> <span class='hs-varid'>rawApplication</span> <span class='hs-varid'>request</span> <span class='hs-layout'>(</span><span class='hs-varid'>respond</span> <span class='hs-varop'>.</span> <span class='hs-varid'>succeedWith</span><span class='hs-layout'>)</span>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
60
src/Servant-API-ReqBody.html
Normal file
60
src/Servant-API-ReqBody.html
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant/API/ReqBody.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE PolyKinds #-}</span>
|
||||||
|
<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
|
||||||
|
<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE TypeOperators #-}</span>
|
||||||
|
<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE FlexibleInstances #-}</span>
|
||||||
|
<a name="line-5"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
|
||||||
|
<a name="line-6"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>ReqBody</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-7"></a>
|
||||||
|
<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Applicative</span>
|
||||||
|
<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Aeson</span>
|
||||||
|
<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
|
||||||
|
<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
|
||||||
|
<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Sub</span>
|
||||||
|
<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
|
||||||
|
<a name="line-14"></a>
|
||||||
|
<a name="line-15"></a><a name="HasServer"></a><span class='hs-comment'>-- | Extract the request body as a value of type @a@.</span>
|
||||||
|
<a name="line-16"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-17"></a><a name="HasServer"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-18"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-19"></a><a name="HasServer"></a><span class='hs-comment'>-- > -- POST /books</span>
|
||||||
|
<a name="line-20"></a><a name="HasServer"></a><span class='hs-comment'>-- > type MyApi = "books" :> ReqBody Book :> Post Book</span>
|
||||||
|
<a name="line-21"></a><a name="HasServer"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>ReqBody</span> <span class='hs-varid'>a</span>
|
||||||
|
<a name="line-22"></a>
|
||||||
|
<a name="line-23"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- | If you use 'ReqBody' in one of the endpoints for your API,</span>
|
||||||
|
<a name="line-24"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- this automatically requires your server-side handler to be a function</span>
|
||||||
|
<a name="line-25"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- that takes an argument of the type specified by 'ReqBody'.</span>
|
||||||
|
<a name="line-26"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- This lets servant worry about extracting it from the request and turning</span>
|
||||||
|
<a name="line-27"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- it into a value of the type you specify.</span>
|
||||||
|
<a name="line-28"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-29"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- All it asks is for a 'FromJSON' instance.</span>
|
||||||
|
<a name="line-30"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-31"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-32"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-33"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > type MyApi = "books" :> ReqBody Book :> Post Book</span>
|
||||||
|
<a name="line-34"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- ></span>
|
||||||
|
<a name="line-35"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > server :: Server MyApi</span>
|
||||||
|
<a name="line-36"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > server = postBook</span>
|
||||||
|
<a name="line-37"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > where postBook :: Book -> EitherT (Int, String) IO Book</span>
|
||||||
|
<a name="line-38"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- > postBook book = ...insert into your db...</span>
|
||||||
|
<a name="line-39"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>FromJSON</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-40"></a> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-conid'>ReqBody</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-41"></a>
|
||||||
|
<a name="line-42"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-conid'>ReqBody</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-43"></a> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Server</span> <span class='hs-varid'>sublayout</span>
|
||||||
|
<a name="line-44"></a>
|
||||||
|
<a name="line-45"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>subserver</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-46"></a> <span class='hs-varid'>mrqbody</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>decode'</span> <span class='hs-varop'><$></span> <span class='hs-varid'>lazyRequestBody</span> <span class='hs-varid'>request</span>
|
||||||
|
<a name="line-47"></a> <span class='hs-keyword'>case</span> <span class='hs-varid'>mrqbody</span> <span class='hs-keyword'>of</span>
|
||||||
|
<a name="line-48"></a> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>InvalidBody</span>
|
||||||
|
<a name="line-49"></a> <span class='hs-conid'>Just</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>route</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>subserver</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
47
src/Servant-API-Sub.html
Normal file
47
src/Servant-API-Sub.html
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant/API/Sub.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE PolyKinds #-}</span>
|
||||||
|
<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
|
||||||
|
<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE TypeOperators #-}</span>
|
||||||
|
<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
|
||||||
|
<a name="line-5"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Sub</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-6"></a>
|
||||||
|
<a name="line-7"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
|
||||||
|
<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>String</span><span class='hs-varop'>.</span><span class='hs-conid'>Conversions</span>
|
||||||
|
<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>TypeLits</span>
|
||||||
|
<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
|
||||||
|
<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
|
||||||
|
<a name="line-12"></a>
|
||||||
|
<a name="line-13"></a><span class='hs-comment'>-- | The contained API (second argument) can be found under @("/" ++ path)@</span>
|
||||||
|
<a name="line-14"></a><span class='hs-comment'>-- (path being the first argument).</span>
|
||||||
|
<a name="line-15"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-16"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-17"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-18"></a><span class='hs-comment'>-- > -- GET /hello/world</span>
|
||||||
|
<a name="line-19"></a><span class='hs-comment'>-- > -- returning a JSON encoded World value</span>
|
||||||
|
<a name="line-20"></a><span class='hs-comment'>-- > type MyApi = "hello" :> "world" :> Get World</span>
|
||||||
|
<a name="line-21"></a><span class='hs-keyword'>data</span> <span class='hs-layout'>(</span><span class='hs-varid'>path</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>k</span><span class='hs-layout'>)</span> <span class='hs-conop'>:></span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>path</span> <span class='hs-conop'>:></span> <span class='hs-varid'>a</span>
|
||||||
|
<a name="line-22"></a><span class='hs-keyword'>infixr</span> <span class='hs-num'>9</span> <span class='hs-conop'>:></span>
|
||||||
|
<a name="line-23"></a>
|
||||||
|
<a name="line-24"></a><a name="instance%20HasServer%20(path%20:%3e%20sublayout)"></a><span class='hs-comment'>-- | Make sure the incoming request starts with @"/path"@, strip it and</span>
|
||||||
|
<a name="line-25"></a><a name="instance%20HasServer%20(path%20:%3e%20sublayout)"></a><span class='hs-comment'>-- pass the rest of the request path to @sublayout@.</span>
|
||||||
|
<a name="line-26"></a><a name="instance%20HasServer%20(path%20:%3e%20sublayout)"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>KnownSymbol</span> <span class='hs-varid'>path</span><span class='hs-layout'>,</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-varid'>path</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-27"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-varid'>path</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Server</span> <span class='hs-varid'>sublayout</span>
|
||||||
|
<a name="line-28"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>subserver</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span> <span class='hs-keyword'>of</span>
|
||||||
|
<a name="line-29"></a> <span class='hs-layout'>(</span><span class='hs-varid'>first</span> <span class='hs-conop'>:</span> <span class='hs-varid'>rest</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-30"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>first</span> <span class='hs-varop'>==</span> <span class='hs-varid'>cs</span> <span class='hs-layout'>(</span><span class='hs-varid'>symbolVal</span> <span class='hs-varid'>proxyPath</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-31"></a> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>route</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-varid'>subserver</span> <span class='hs-varid'>request</span><span class='hs-layout'>{</span>
|
||||||
|
<a name="line-32"></a> <span class='hs-varid'>pathInfo</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>rest</span>
|
||||||
|
<a name="line-33"></a> <span class='hs-layout'>}</span> <span class='hs-varid'>respond</span>
|
||||||
|
<a name="line-34"></a> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>NotFound</span>
|
||||||
|
<a name="line-35"></a>
|
||||||
|
<a name="line-36"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>proxyPath</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>path</span>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
62
src/Servant-API.html
Normal file
62
src/Servant-API.html
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant/API.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span> <span class='hs-layout'>(</span>
|
||||||
|
<a name="line-2"></a>
|
||||||
|
<a name="line-3"></a> <span class='hs-comment'>-- * Combinators</span>
|
||||||
|
<a name="line-4"></a> <span class='hs-comment'>-- | Type-level combinator for expressing subrouting: @':>'@</span>
|
||||||
|
<a name="line-5"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Sub</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-6"></a> <span class='hs-comment'>-- | Type-level combinator for alternative endpoints: @':<|>'@</span>
|
||||||
|
<a name="line-7"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Alternative</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-8"></a>
|
||||||
|
<a name="line-9"></a> <span class='hs-comment'>-- * Accessing information from the request</span>
|
||||||
|
<a name="line-10"></a> <span class='hs-comment'>-- | Capturing parts of the url path as parsed values: @'Capture'@</span>
|
||||||
|
<a name="line-11"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Capture</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-12"></a> <span class='hs-comment'>-- | Retrieving parameters from the query string of the 'URI': @'QueryParam'@</span>
|
||||||
|
<a name="line-13"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>QueryParam</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-14"></a> <span class='hs-comment'>-- | Accessing the request body as a JSON-encoded type: @'ReqBody'@</span>
|
||||||
|
<a name="line-15"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>ReqBody</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-16"></a>
|
||||||
|
<a name="line-17"></a> <span class='hs-comment'>-- * Actual endpoints, distinguished by HTTP method</span>
|
||||||
|
<a name="line-18"></a> <span class='hs-comment'>-- | GET requests</span>
|
||||||
|
<a name="line-19"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Get</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-20"></a> <span class='hs-comment'>-- | POST requests</span>
|
||||||
|
<a name="line-21"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Post</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-22"></a> <span class='hs-comment'>-- | DELETE requests</span>
|
||||||
|
<a name="line-23"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Delete</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-24"></a> <span class='hs-comment'>-- | PUT requests</span>
|
||||||
|
<a name="line-25"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Put</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-26"></a>
|
||||||
|
<a name="line-27"></a> <span class='hs-comment'>-- * Untyped endpoints</span>
|
||||||
|
<a name="line-28"></a> <span class='hs-comment'>-- | Plugging in a wai 'Network.Wai.Application', serving directories</span>
|
||||||
|
<a name="line-29"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Raw</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-30"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>StaticFiles</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-31"></a>
|
||||||
|
<a name="line-32"></a> <span class='hs-comment'>-- * Utilities</span>
|
||||||
|
<a name="line-33"></a> <span class='hs-comment'>-- | QuasiQuotes for endpoints</span>
|
||||||
|
<a name="line-34"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>QQ</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-35"></a> <span class='hs-comment'>-- | Type-safe internal URLs</span>
|
||||||
|
<a name="line-36"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>Links</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-37"></a> <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-38"></a>
|
||||||
|
<a name="line-39"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Alternative</span>
|
||||||
|
<a name="line-40"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Capture</span>
|
||||||
|
<a name="line-41"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Delete</span>
|
||||||
|
<a name="line-42"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Get</span>
|
||||||
|
<a name="line-43"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Post</span>
|
||||||
|
<a name="line-44"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Put</span>
|
||||||
|
<a name="line-45"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>QueryParam</span>
|
||||||
|
<a name="line-46"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Raw</span>
|
||||||
|
<a name="line-47"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>ReqBody</span>
|
||||||
|
<a name="line-48"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Sub</span>
|
||||||
|
<a name="line-49"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>QQ</span> <span class='hs-layout'>(</span><span class='hs-varid'>sitemap</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-50"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>Links</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkLink</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-51"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>StaticFiles</span>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
141
src/Servant-Common-Text.html
Normal file
141
src/Servant-Common-Text.html
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant/Common/Text.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE FlexibleInstances #-}</span>
|
||||||
|
<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE OverloadedStrings #-}</span>
|
||||||
|
<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE TypeSynonymInstances #-}</span>
|
||||||
|
<a name="line-4"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Common</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span>
|
||||||
|
<a name="line-5"></a> <span class='hs-layout'>(</span> <span class='hs-conid'>FromText</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-6"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>ToText</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-7"></a> <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-8"></a>
|
||||||
|
<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>String</span><span class='hs-varop'>.</span><span class='hs-conid'>Conversions</span>
|
||||||
|
<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Int</span>
|
||||||
|
<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span>
|
||||||
|
<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span><span class='hs-varop'>.</span><span class='hs-conid'>Read</span>
|
||||||
|
<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Word</span>
|
||||||
|
<a name="line-14"></a>
|
||||||
|
<a name="line-15"></a><a name="FromText"></a><span class='hs-comment'>-- | For getting values from url captures and query string parameters</span>
|
||||||
|
<a name="line-16"></a><a name="FromText"></a><span class='hs-keyword'>class</span> <span class='hs-conid'>FromText</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-17"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Text</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Maybe</span> <span class='hs-varid'>a</span>
|
||||||
|
<a name="line-18"></a>
|
||||||
|
<a name="line-19"></a><a name="ToText"></a><span class='hs-comment'>-- | For putting values in paths and query string parameters</span>
|
||||||
|
<a name="line-20"></a><a name="ToText"></a><span class='hs-keyword'>class</span> <span class='hs-conid'>ToText</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-21"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Text</span>
|
||||||
|
<a name="line-22"></a>
|
||||||
|
<a name="line-23"></a><a name="instance%20FromText%20Text"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Text</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-24"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span>
|
||||||
|
<a name="line-25"></a>
|
||||||
|
<a name="line-26"></a><a name="instance%20ToText%20Text"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Text</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-27"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>id</span>
|
||||||
|
<a name="line-28"></a>
|
||||||
|
<a name="line-29"></a><a name="instance%20FromText%20String"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>String</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-30"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-varop'>.</span> <span class='hs-varid'>cs</span>
|
||||||
|
<a name="line-31"></a>
|
||||||
|
<a name="line-32"></a><a name="instance%20ToText%20String"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>String</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-33"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span>
|
||||||
|
<a name="line-34"></a>
|
||||||
|
<a name="line-35"></a><a name="instance%20FromText%20Bool"></a><span class='hs-comment'>-- |</span>
|
||||||
|
<a name="line-36"></a><a name="instance%20FromText%20Bool"></a><span class='hs-comment'>-- > fromText "true" = Just True</span>
|
||||||
|
<a name="line-37"></a><a name="instance%20FromText%20Bool"></a><span class='hs-comment'>-- > fromText "false" = Just False</span>
|
||||||
|
<a name="line-38"></a><a name="instance%20FromText%20Bool"></a><span class='hs-comment'>-- > fromText _ = Nothing</span>
|
||||||
|
<a name="line-39"></a><a name="instance%20FromText%20Bool"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Bool</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-40"></a> <span class='hs-varid'>fromText</span> <span class='hs-str'>"true"</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-conid'>True</span>
|
||||||
|
<a name="line-41"></a> <span class='hs-varid'>fromText</span> <span class='hs-str'>"false"</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-conid'>False</span>
|
||||||
|
<a name="line-42"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
|
||||||
|
<a name="line-43"></a>
|
||||||
|
<a name="line-44"></a><a name="instance%20ToText%20Bool"></a><span class='hs-comment'>-- |</span>
|
||||||
|
<a name="line-45"></a><a name="instance%20ToText%20Bool"></a><span class='hs-comment'>-- > toText True = "true"</span>
|
||||||
|
<a name="line-46"></a><a name="instance%20ToText%20Bool"></a><span class='hs-comment'>-- > toText False = "false"</span>
|
||||||
|
<a name="line-47"></a><a name="instance%20ToText%20Bool"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Bool</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-48"></a> <span class='hs-varid'>toText</span> <span class='hs-conid'>True</span> <span class='hs-keyglyph'>=</span> <span class='hs-str'>"true"</span>
|
||||||
|
<a name="line-49"></a> <span class='hs-varid'>toText</span> <span class='hs-conid'>False</span> <span class='hs-keyglyph'>=</span> <span class='hs-str'>"false"</span>
|
||||||
|
<a name="line-50"></a>
|
||||||
|
<a name="line-51"></a><a name="instance%20FromText%20Int"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Int</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-52"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-layout'>(</span><span class='hs-varid'>signed</span> <span class='hs-varid'>decimal</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-53"></a>
|
||||||
|
<a name="line-54"></a><a name="instance%20ToText%20Int"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Int</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-55"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
|
||||||
|
<a name="line-56"></a>
|
||||||
|
<a name="line-57"></a><a name="instance%20FromText%20Int8"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Int8</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-58"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-layout'>(</span><span class='hs-varid'>signed</span> <span class='hs-varid'>decimal</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-59"></a>
|
||||||
|
<a name="line-60"></a><a name="instance%20ToText%20Int8"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Int8</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-61"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
|
||||||
|
<a name="line-62"></a>
|
||||||
|
<a name="line-63"></a><a name="instance%20FromText%20Int16"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Int16</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-64"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-layout'>(</span><span class='hs-varid'>signed</span> <span class='hs-varid'>decimal</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-65"></a>
|
||||||
|
<a name="line-66"></a><a name="instance%20ToText%20Int16"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Int16</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-67"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
|
||||||
|
<a name="line-68"></a>
|
||||||
|
<a name="line-69"></a><a name="instance%20FromText%20Int32"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Int32</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-70"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-layout'>(</span><span class='hs-varid'>signed</span> <span class='hs-varid'>decimal</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-71"></a>
|
||||||
|
<a name="line-72"></a><a name="instance%20ToText%20Int32"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Int32</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-73"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
|
||||||
|
<a name="line-74"></a>
|
||||||
|
<a name="line-75"></a><a name="instance%20FromText%20Int64"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Int64</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-76"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-layout'>(</span><span class='hs-varid'>signed</span> <span class='hs-varid'>decimal</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-77"></a>
|
||||||
|
<a name="line-78"></a><a name="instance%20ToText%20Int64"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Int64</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-79"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
|
||||||
|
<a name="line-80"></a>
|
||||||
|
<a name="line-81"></a><a name="instance%20FromText%20Word"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Word</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-82"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-varid'>decimal</span>
|
||||||
|
<a name="line-83"></a>
|
||||||
|
<a name="line-84"></a><a name="instance%20ToText%20Word"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Word</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-85"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
|
||||||
|
<a name="line-86"></a>
|
||||||
|
<a name="line-87"></a><a name="instance%20FromText%20Word8"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Word8</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-88"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-varid'>decimal</span>
|
||||||
|
<a name="line-89"></a>
|
||||||
|
<a name="line-90"></a><a name="instance%20ToText%20Word8"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Word8</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-91"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
|
||||||
|
<a name="line-92"></a>
|
||||||
|
<a name="line-93"></a><a name="instance%20FromText%20Word16"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Word16</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-94"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-varid'>decimal</span>
|
||||||
|
<a name="line-95"></a>
|
||||||
|
<a name="line-96"></a><a name="instance%20ToText%20Word16"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Word16</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-97"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
|
||||||
|
<a name="line-98"></a>
|
||||||
|
<a name="line-99"></a><a name="instance%20FromText%20Word32"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Word32</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-100"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-varid'>decimal</span>
|
||||||
|
<a name="line-101"></a>
|
||||||
|
<a name="line-102"></a><a name="instance%20ToText%20Word32"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Word32</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-103"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
|
||||||
|
<a name="line-104"></a>
|
||||||
|
<a name="line-105"></a><a name="instance%20FromText%20Word64"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Word64</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-106"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-varid'>decimal</span>
|
||||||
|
<a name="line-107"></a>
|
||||||
|
<a name="line-108"></a><a name="instance%20ToText%20Word64"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Word64</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-109"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
|
||||||
|
<a name="line-110"></a>
|
||||||
|
<a name="line-111"></a><a name="instance%20FromText%20Integer"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Integer</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-112"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-varid'>decimal</span>
|
||||||
|
<a name="line-113"></a>
|
||||||
|
<a name="line-114"></a><a name="instance%20ToText%20Integer"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Integer</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-115"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
|
||||||
|
<a name="line-116"></a>
|
||||||
|
<a name="line-117"></a><a name="instance%20FromText%20Double"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Double</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-118"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-varid'>rational</span>
|
||||||
|
<a name="line-119"></a>
|
||||||
|
<a name="line-120"></a><a name="instance%20ToText%20Double"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Double</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-121"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
|
||||||
|
<a name="line-122"></a>
|
||||||
|
<a name="line-123"></a><a name="instance%20FromText%20Float"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Float</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-124"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-varid'>rational</span>
|
||||||
|
<a name="line-125"></a>
|
||||||
|
<a name="line-126"></a><a name="instance%20ToText%20Float"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Float</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-127"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
|
||||||
|
<a name="line-128"></a>
|
||||||
|
<a name="line-129"></a><a name="runReader"></a><span class='hs-definition'>runReader</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Reader</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Text</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Maybe</span> <span class='hs-varid'>a</span>
|
||||||
|
<a name="line-130"></a><span class='hs-definition'>runReader</span> <span class='hs-varid'>reader</span> <span class='hs-varid'>t</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>either</span> <span class='hs-layout'>(</span><span class='hs-varid'>const</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varop'>.</span> <span class='hs-varid'>fst</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-varid'>reader</span> <span class='hs-varid'>t</span>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
209
src/Servant-QQ.html
Normal file
209
src/Servant-QQ.html
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant/QQ.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE MultiParamTypeClasses #-}</span>
|
||||||
|
<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE FunctionalDependencies #-}</span>
|
||||||
|
<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE DataKinds #-}</span>
|
||||||
|
<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE FlexibleInstances #-}</span>
|
||||||
|
<a name="line-5"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
|
||||||
|
<a name="line-6"></a><span class='hs-comment'>{-# LANGUAGE TemplateHaskell #-}</span>
|
||||||
|
<a name="line-7"></a><span class='hs-comment'>{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}</span>
|
||||||
|
<a name="line-8"></a><span class='hs-comment'>-- | QuasiQuoting utilities for API types.</span>
|
||||||
|
<a name="line-9"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-10"></a><span class='hs-comment'>-- 'sitemap' allows you to write your type in a very natural way:</span>
|
||||||
|
<a name="line-11"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-12"></a><span class='hs-comment'>-- @</span>
|
||||||
|
<a name="line-13"></a><span class='hs-comment'>-- [sitemap|</span>
|
||||||
|
<a name="line-14"></a><span class='hs-comment'>-- PUT hello String -> ()</span>
|
||||||
|
<a name="line-15"></a><span class='hs-comment'>-- POST hello/p:Int String -> ()</span>
|
||||||
|
<a name="line-16"></a><span class='hs-comment'>-- GET hello/?name:String Int</span>
|
||||||
|
<a name="line-17"></a><span class='hs-comment'>-- |]</span>
|
||||||
|
<a name="line-18"></a><span class='hs-comment'>-- @</span>
|
||||||
|
<a name="line-19"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-20"></a><span class='hs-comment'>-- Will generate:</span>
|
||||||
|
<a name="line-21"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-22"></a><span class='hs-comment'>-- @</span>
|
||||||
|
<a name="line-23"></a><span class='hs-comment'>-- "hello" :> ReqBody String :> Put ()</span>
|
||||||
|
<a name="line-24"></a><span class='hs-comment'>-- :\<|> "hello" :> Capture "p" Int :> ReqBody String :> Post ()</span>
|
||||||
|
<a name="line-25"></a><span class='hs-comment'>-- :\<|> "hello" :> QueryParam "name" String :> Get Int</span>
|
||||||
|
<a name="line-26"></a><span class='hs-comment'>-- @</span>
|
||||||
|
<a name="line-27"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-28"></a><span class='hs-comment'>-- Note the @/@ before a @QueryParam@!</span>
|
||||||
|
<a name="line-29"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>QQ</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-30"></a>
|
||||||
|
<a name="line-31"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span> <span class='hs-layout'>(</span><span class='hs-varid'>void</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-32"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Applicative</span> <span class='hs-varid'>hiding</span> <span class='hs-layout'>(</span><span class='hs-varid'>many</span><span class='hs-layout'>,</span> <span class='hs-layout'>(</span><span class='hs-varop'><|></span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>optional</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-33"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Language</span><span class='hs-varop'>.</span><span class='hs-conid'>Haskell</span><span class='hs-varop'>.</span><span class='hs-conid'>TH</span><span class='hs-varop'>.</span><span class='hs-conid'>Quote</span>
|
||||||
|
<a name="line-34"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Language</span><span class='hs-varop'>.</span><span class='hs-conid'>Haskell</span><span class='hs-varop'>.</span><span class='hs-conid'>TH</span>
|
||||||
|
<a name="line-35"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Text</span><span class='hs-varop'>.</span><span class='hs-conid'>ParserCombinators</span><span class='hs-varop'>.</span><span class='hs-conid'>Parsec</span>
|
||||||
|
<a name="line-36"></a>
|
||||||
|
<a name="line-37"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Capture</span>
|
||||||
|
<a name="line-38"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Get</span>
|
||||||
|
<a name="line-39"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Post</span>
|
||||||
|
<a name="line-40"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Put</span>
|
||||||
|
<a name="line-41"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Delete</span>
|
||||||
|
<a name="line-42"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>QueryParam</span>
|
||||||
|
<a name="line-43"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>ReqBody</span>
|
||||||
|
<a name="line-44"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Sub</span>
|
||||||
|
<a name="line-45"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Alternative</span>
|
||||||
|
<a name="line-46"></a>
|
||||||
|
<a name="line-47"></a><a name="ExpSYM"></a><span class='hs-comment'>-- | Finally-tagless encoding for our DSL.</span>
|
||||||
|
<a name="line-48"></a><a name="ExpSYM"></a><span class='hs-comment'>-- Keeping 'repr'' and 'repr' distinct when writing functions with an</span>
|
||||||
|
<a name="line-49"></a><a name="ExpSYM"></a><span class='hs-comment'>-- @ExpSYM@ context ensures certain invariants (for instance, that there is</span>
|
||||||
|
<a name="line-50"></a><a name="ExpSYM"></a><span class='hs-comment'>-- only one of 'get', 'post', 'put', and 'delete' in a value), but</span>
|
||||||
|
<a name="line-51"></a><a name="ExpSYM"></a><span class='hs-comment'>-- sometimes requires a little more work.</span>
|
||||||
|
<a name="line-52"></a><a name="ExpSYM"></a><span class='hs-keyword'>class</span> <span class='hs-conid'>ExpSYM</span> <span class='hs-varid'>repr'</span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr'</span><span class='hs-layout'>,</span> <span class='hs-varid'>repr'</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-53"></a> <span class='hs-varid'>lit</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr'</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span>
|
||||||
|
<a name="line-54"></a> <span class='hs-varid'>capture</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span>
|
||||||
|
<a name="line-55"></a> <span class='hs-varid'>reqBody</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span>
|
||||||
|
<a name="line-56"></a> <span class='hs-varid'>queryParam</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span>
|
||||||
|
<a name="line-57"></a> <span class='hs-varid'>conj</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>repr'</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span>
|
||||||
|
<a name="line-58"></a> <span class='hs-varid'>get</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span>
|
||||||
|
<a name="line-59"></a> <span class='hs-varid'>post</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span>
|
||||||
|
<a name="line-60"></a> <span class='hs-varid'>put</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span>
|
||||||
|
<a name="line-61"></a> <span class='hs-varid'>delete</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span>
|
||||||
|
<a name="line-62"></a>
|
||||||
|
<a name="line-63"></a>
|
||||||
|
<a name="line-64"></a><span class='hs-keyword'>infixr</span> <span class='hs-num'>6</span> <span class='hs-varop'>>:</span>
|
||||||
|
<a name="line-65"></a>
|
||||||
|
<a name="line-66"></a><a name="%3e:"></a><span class='hs-layout'>(</span><span class='hs-varop'>>:</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Type</span>
|
||||||
|
<a name="line-67"></a><span class='hs-layout'>(</span><span class='hs-varop'>>:</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>conj</span>
|
||||||
|
<a name="line-68"></a>
|
||||||
|
<a name="line-69"></a>
|
||||||
|
<a name="line-70"></a><a name="instance%20ExpSYM%20Type%20Type"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ExpSYM</span> <span class='hs-conid'>Type</span> <span class='hs-conid'>Type</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-71"></a> <span class='hs-varid'>lit</span> <span class='hs-varid'>name</span> <span class='hs-varid'>r</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>LitT</span> <span class='hs-layout'>(</span><span class='hs-conid'>StrTyLit</span> <span class='hs-varid'>name</span><span class='hs-layout'>)</span> <span class='hs-varop'>>:</span> <span class='hs-varid'>r</span>
|
||||||
|
<a name="line-72"></a> <span class='hs-varid'>capture</span> <span class='hs-varid'>name</span> <span class='hs-varid'>typ</span> <span class='hs-varid'>r</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-conid'>Capture</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>LitT</span> <span class='hs-layout'>(</span><span class='hs-conid'>StrTyLit</span> <span class='hs-varid'>name</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-73"></a> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mkName</span> <span class='hs-varid'>typ</span><span class='hs-layout'>)</span> <span class='hs-varop'>>:</span> <span class='hs-varid'>r</span>
|
||||||
|
<a name="line-74"></a> <span class='hs-varid'>reqBody</span> <span class='hs-varid'>typ</span> <span class='hs-varid'>r</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-conid'>ReqBody</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mkName</span> <span class='hs-varid'>typ</span><span class='hs-layout'>)</span> <span class='hs-varop'>>:</span> <span class='hs-varid'>r</span>
|
||||||
|
<a name="line-75"></a> <span class='hs-varid'>queryParam</span> <span class='hs-varid'>name</span> <span class='hs-varid'>typ</span> <span class='hs-varid'>r</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-conid'>QueryParam</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>LitT</span> <span class='hs-layout'>(</span><span class='hs-conid'>StrTyLit</span> <span class='hs-varid'>name</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-76"></a> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mkName</span> <span class='hs-varid'>typ</span><span class='hs-layout'>)</span> <span class='hs-varop'>>:</span> <span class='hs-varid'>r</span>
|
||||||
|
<a name="line-77"></a> <span class='hs-varid'>conj</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-layout'>(</span><span class='hs-conop'>:></span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-78"></a> <span class='hs-varid'>get</span> <span class='hs-varid'>typ</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-conid'>Get</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mkName</span> <span class='hs-varid'>typ</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-79"></a> <span class='hs-varid'>post</span> <span class='hs-varid'>typ</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-conid'>Post</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mkName</span> <span class='hs-varid'>typ</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-80"></a> <span class='hs-varid'>put</span> <span class='hs-varid'>typ</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-conid'>Put</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mkName</span> <span class='hs-varid'>typ</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-81"></a> <span class='hs-varid'>delete</span> <span class='hs-str'>"()"</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-conid'>Delete</span>
|
||||||
|
<a name="line-82"></a> <span class='hs-varid'>delete</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>error</span> <span class='hs-str'>"Delete does not return a request body"</span>
|
||||||
|
<a name="line-83"></a>
|
||||||
|
<a name="line-84"></a><a name="parseMethod"></a><span class='hs-definition'>parseMethod</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ExpSYM</span> <span class='hs-varid'>repr'</span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>Parser</span> <span class='hs-layout'>(</span><span class='hs-conid'>String</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-85"></a><span class='hs-definition'>parseMethod</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>try</span> <span class='hs-layout'>(</span><span class='hs-varid'>string</span> <span class='hs-str'>"GET"</span> <span class='hs-varop'>>></span> <span class='hs-varid'>return</span> <span class='hs-varid'>get</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-86"></a> <span class='hs-varop'><|></span> <span class='hs-varid'>try</span> <span class='hs-layout'>(</span><span class='hs-varid'>string</span> <span class='hs-str'>"POST"</span> <span class='hs-varop'>>></span> <span class='hs-varid'>return</span> <span class='hs-varid'>post</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-87"></a> <span class='hs-varop'><|></span> <span class='hs-varid'>try</span> <span class='hs-layout'>(</span><span class='hs-varid'>string</span> <span class='hs-str'>"PUT"</span> <span class='hs-varop'>>></span> <span class='hs-varid'>return</span> <span class='hs-varid'>put</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-88"></a> <span class='hs-varop'><|></span> <span class='hs-varid'>try</span> <span class='hs-layout'>(</span><span class='hs-varid'>string</span> <span class='hs-str'>"DELETE"</span> <span class='hs-varop'>>></span> <span class='hs-varid'>return</span> <span class='hs-varid'>delete</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-89"></a>
|
||||||
|
<a name="line-90"></a><a name="parseUrlSegment"></a><span class='hs-definition'>parseUrlSegment</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ExpSYM</span> <span class='hs-varid'>repr</span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>Parser</span> <span class='hs-layout'>(</span><span class='hs-varid'>repr</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-91"></a><span class='hs-definition'>parseUrlSegment</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>try</span> <span class='hs-varid'>parseCapture</span>
|
||||||
|
<a name="line-92"></a> <span class='hs-varop'><|></span> <span class='hs-varid'>try</span> <span class='hs-varid'>parseQueryParam</span>
|
||||||
|
<a name="line-93"></a> <span class='hs-varop'><|></span> <span class='hs-varid'>try</span> <span class='hs-varid'>parseLit</span>
|
||||||
|
<a name="line-94"></a> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-95"></a> <span class='hs-varid'>parseCapture</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-96"></a> <span class='hs-varid'>cname</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>many</span> <span class='hs-layout'>(</span><span class='hs-varid'>noneOf</span> <span class='hs-str'>" ?/:"</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-97"></a> <span class='hs-varid'>char</span> <span class='hs-chr'>':'</span>
|
||||||
|
<a name="line-98"></a> <span class='hs-varid'>ctyp</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>many</span> <span class='hs-layout'>(</span><span class='hs-varid'>noneOf</span> <span class='hs-str'>" ?/:"</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-99"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>capture</span> <span class='hs-varid'>cname</span> <span class='hs-varid'>ctyp</span>
|
||||||
|
<a name="line-100"></a> <span class='hs-varid'>parseQueryParam</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-101"></a> <span class='hs-varid'>char</span> <span class='hs-chr'>'?'</span>
|
||||||
|
<a name="line-102"></a> <span class='hs-varid'>cname</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>many</span> <span class='hs-layout'>(</span><span class='hs-varid'>noneOf</span> <span class='hs-str'>" ?/:"</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-103"></a> <span class='hs-varid'>char</span> <span class='hs-chr'>':'</span>
|
||||||
|
<a name="line-104"></a> <span class='hs-varid'>ctyp</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>many</span> <span class='hs-layout'>(</span><span class='hs-varid'>noneOf</span> <span class='hs-str'>" ?/:"</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-105"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>queryParam</span> <span class='hs-varid'>cname</span> <span class='hs-varid'>ctyp</span>
|
||||||
|
<a name="line-106"></a> <span class='hs-varid'>parseLit</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lit</span> <span class='hs-varop'><$></span> <span class='hs-varid'>many</span> <span class='hs-layout'>(</span><span class='hs-varid'>noneOf</span> <span class='hs-str'>" ?/:"</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-107"></a>
|
||||||
|
<a name="line-108"></a><a name="parseUrl"></a><span class='hs-definition'>parseUrl</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ExpSYM</span> <span class='hs-varid'>repr</span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>Parser</span> <span class='hs-layout'>(</span><span class='hs-varid'>repr</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>repr</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-109"></a><span class='hs-definition'>parseUrl</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-110"></a> <span class='hs-varid'>optional</span> <span class='hs-varop'>$</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'/'</span>
|
||||||
|
<a name="line-111"></a> <span class='hs-varid'>url</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>parseUrlSegment</span> <span class='hs-varop'>`sepBy1`</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'/'</span>
|
||||||
|
<a name="line-112"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>foldr1</span> <span class='hs-layout'>(</span><span class='hs-varop'>.</span><span class='hs-layout'>)</span> <span class='hs-varid'>url</span>
|
||||||
|
<a name="line-113"></a>
|
||||||
|
<a name="line-114"></a><a name="Typ"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Typ</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Val</span> <span class='hs-conid'>String</span>
|
||||||
|
<a name="line-115"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ReqArgVal</span> <span class='hs-conid'>String</span> <span class='hs-conid'>String</span>
|
||||||
|
<a name="line-116"></a>
|
||||||
|
<a name="line-117"></a><a name="parseTyp"></a><span class='hs-definition'>parseTyp</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Parser</span> <span class='hs-conid'>Typ</span>
|
||||||
|
<a name="line-118"></a><span class='hs-definition'>parseTyp</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-119"></a> <span class='hs-varid'>f</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>many</span> <span class='hs-layout'>(</span><span class='hs-varid'>noneOf</span> <span class='hs-str'>"-{\n\r"</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-120"></a> <span class='hs-varid'>spaces</span>
|
||||||
|
<a name="line-121"></a> <span class='hs-varid'>s</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>optionMaybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>try</span> <span class='hs-varid'>parseRet</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-122"></a> <span class='hs-varid'>try</span> <span class='hs-varop'>$</span> <span class='hs-varid'>optional</span> <span class='hs-varid'>inlineComment</span>
|
||||||
|
<a name="line-123"></a> <span class='hs-varid'>try</span> <span class='hs-varop'>$</span> <span class='hs-varid'>optional</span> <span class='hs-varid'>blockComment</span>
|
||||||
|
<a name="line-124"></a> <span class='hs-keyword'>case</span> <span class='hs-varid'>s</span> <span class='hs-keyword'>of</span>
|
||||||
|
<a name="line-125"></a> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Val</span> <span class='hs-layout'>(</span><span class='hs-varid'>stripTr</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-126"></a> <span class='hs-conid'>Just</span> <span class='hs-varid'>s'</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-conid'>ReqArgVal</span> <span class='hs-layout'>(</span><span class='hs-varid'>stripTr</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>stripTr</span> <span class='hs-varid'>s'</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-127"></a> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-128"></a> <span class='hs-varid'>parseRet</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Parser</span> <span class='hs-conid'>String</span>
|
||||||
|
<a name="line-129"></a> <span class='hs-varid'>parseRet</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-130"></a> <span class='hs-varid'>string</span> <span class='hs-str'>"->"</span>
|
||||||
|
<a name="line-131"></a> <span class='hs-varid'>spaces</span>
|
||||||
|
<a name="line-132"></a> <span class='hs-varid'>many</span> <span class='hs-layout'>(</span><span class='hs-varid'>noneOf</span> <span class='hs-str'>"-{\n\r"</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-133"></a> <span class='hs-varid'>stripTr</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>reverse</span> <span class='hs-varop'>.</span> <span class='hs-varid'>dropWhile</span> <span class='hs-layout'>(</span><span class='hs-varop'>==</span> <span class='hs-chr'>' '</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-varid'>reverse</span>
|
||||||
|
<a name="line-134"></a>
|
||||||
|
<a name="line-135"></a>
|
||||||
|
<a name="line-136"></a><a name="parseEntry"></a><span class='hs-definition'>parseEntry</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ExpSYM</span> <span class='hs-varid'>repr</span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>Parser</span> <span class='hs-varid'>repr</span>
|
||||||
|
<a name="line-137"></a><span class='hs-definition'>parseEntry</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-138"></a> <span class='hs-varid'>met</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>parseMethod</span>
|
||||||
|
<a name="line-139"></a> <span class='hs-varid'>spaces</span>
|
||||||
|
<a name="line-140"></a> <span class='hs-varid'>url</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>parseUrl</span>
|
||||||
|
<a name="line-141"></a> <span class='hs-varid'>spaces</span>
|
||||||
|
<a name="line-142"></a> <span class='hs-varid'>typ</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>parseTyp</span>
|
||||||
|
<a name="line-143"></a> <span class='hs-keyword'>case</span> <span class='hs-varid'>typ</span> <span class='hs-keyword'>of</span>
|
||||||
|
<a name="line-144"></a> <span class='hs-conid'>Val</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>url</span> <span class='hs-layout'>(</span><span class='hs-varid'>met</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-145"></a> <span class='hs-conid'>ReqArgVal</span> <span class='hs-varid'>i</span> <span class='hs-varid'>o</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>url</span> <span class='hs-varop'>$</span> <span class='hs-varid'>reqBody</span> <span class='hs-varid'>i</span> <span class='hs-layout'>(</span><span class='hs-varid'>met</span> <span class='hs-varid'>o</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-146"></a>
|
||||||
|
<a name="line-147"></a><a name="blockComment"></a><span class='hs-definition'>blockComment</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Parser</span> <span class='hs-conid'>()</span>
|
||||||
|
<a name="line-148"></a><span class='hs-definition'>blockComment</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-149"></a> <span class='hs-varid'>string</span> <span class='hs-str'>"{-"</span>
|
||||||
|
<a name="line-150"></a> <span class='hs-varid'>manyTill</span> <span class='hs-varid'>anyChar</span> <span class='hs-layout'>(</span><span class='hs-varid'>try</span> <span class='hs-varop'>$</span> <span class='hs-varid'>string</span> <span class='hs-str'>"-}"</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-151"></a> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span>
|
||||||
|
<a name="line-152"></a>
|
||||||
|
<a name="line-153"></a><a name="inlineComment"></a><span class='hs-definition'>inlineComment</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Parser</span> <span class='hs-conid'>()</span>
|
||||||
|
<a name="line-154"></a><span class='hs-definition'>inlineComment</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-155"></a> <span class='hs-varid'>string</span> <span class='hs-str'>"--"</span>
|
||||||
|
<a name="line-156"></a> <span class='hs-varid'>manyTill</span> <span class='hs-varid'>anyChar</span> <span class='hs-layout'>(</span><span class='hs-varid'>try</span> <span class='hs-varop'>$</span> <span class='hs-varid'>lookAhead</span> <span class='hs-varid'>eol</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-157"></a> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span>
|
||||||
|
<a name="line-158"></a>
|
||||||
|
<a name="line-159"></a><a name="eol"></a><span class='hs-definition'>eol</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Parser</span> <span class='hs-conid'>String</span>
|
||||||
|
<a name="line-160"></a><span class='hs-definition'>eol</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>try</span> <span class='hs-layout'>(</span><span class='hs-varid'>string</span> <span class='hs-str'>"\n\r"</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-161"></a> <span class='hs-varop'><|></span> <span class='hs-varid'>try</span> <span class='hs-layout'>(</span><span class='hs-varid'>string</span> <span class='hs-str'>"\r\n"</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-162"></a> <span class='hs-varop'><|></span> <span class='hs-varid'>string</span> <span class='hs-str'>"\n"</span>
|
||||||
|
<a name="line-163"></a> <span class='hs-varop'><|></span> <span class='hs-varid'>string</span> <span class='hs-str'>"\r"</span>
|
||||||
|
<a name="line-164"></a> <span class='hs-varop'><?></span> <span class='hs-str'>"end of line"</span>
|
||||||
|
<a name="line-165"></a>
|
||||||
|
<a name="line-166"></a><a name="eols"></a><span class='hs-definition'>eols</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Parser</span> <span class='hs-conid'>()</span>
|
||||||
|
<a name="line-167"></a><span class='hs-definition'>eols</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>skipMany</span> <span class='hs-varop'>$</span> <span class='hs-varid'>void</span> <span class='hs-varid'>eol</span> <span class='hs-varop'><|></span> <span class='hs-varid'>blockComment</span> <span class='hs-varop'><|></span> <span class='hs-varid'>inlineComment</span>
|
||||||
|
<a name="line-168"></a>
|
||||||
|
<a name="line-169"></a><a name="parseAll"></a><span class='hs-definition'>parseAll</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Parser</span> <span class='hs-conid'>Type</span>
|
||||||
|
<a name="line-170"></a><span class='hs-definition'>parseAll</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-171"></a> <span class='hs-varid'>eols</span>
|
||||||
|
<a name="line-172"></a> <span class='hs-varid'>entries</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>parseEntry</span> <span class='hs-varop'>`endBy`</span> <span class='hs-varid'>eols</span>
|
||||||
|
<a name="line-173"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>foldr1</span> <span class='hs-varid'>union</span> <span class='hs-varid'>entries</span>
|
||||||
|
<a name="line-174"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>union</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Type</span>
|
||||||
|
<a name="line-175"></a> <span class='hs-varid'>union</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-layout'>(</span><span class='hs-conop'>:<|></span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-176"></a>
|
||||||
|
<a name="line-177"></a><a name="sitemap"></a><span class='hs-comment'>-- | The sitemap QuasiQuoter.</span>
|
||||||
|
<a name="line-178"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-179"></a><span class='hs-comment'>-- * @.../<var>:<type>/...@ becomes a capture</span>
|
||||||
|
<a name="line-180"></a><span class='hs-comment'>-- * @.../?<var>:<type>@ becomes a query parameter</span>
|
||||||
|
<a name="line-181"></a><span class='hs-comment'>-- * @<method> ... <typ>@ becomes a method returning @<typ>@</span>
|
||||||
|
<a name="line-182"></a><span class='hs-comment'>-- * @<method> ... <typ1> -> <typ2>@ becomes a method with request</span>
|
||||||
|
<a name="line-183"></a><span class='hs-comment'>-- body of @<typ1>@ and returning @<typ2>@</span>
|
||||||
|
<a name="line-184"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-185"></a><span class='hs-comment'>-- Comments are allowed, and have the standard Haskell format</span>
|
||||||
|
<a name="line-186"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-187"></a><span class='hs-comment'>-- * @--@ for inline</span>
|
||||||
|
<a name="line-188"></a><span class='hs-comment'>-- * @{- ... -}@ for block</span>
|
||||||
|
<a name="line-189"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-190"></a><span class='hs-definition'>sitemap</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>QuasiQuoter</span>
|
||||||
|
<a name="line-191"></a><span class='hs-definition'>sitemap</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>QuasiQuoter</span> <span class='hs-layout'>{</span> <span class='hs-varid'>quoteExp</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>undefined</span>
|
||||||
|
<a name="line-192"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>quotePat</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>undefined</span>
|
||||||
|
<a name="line-193"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>quoteType</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>x</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyword'>case</span> <span class='hs-varid'>parse</span> <span class='hs-varid'>parseAll</span> <span class='hs-str'>""</span> <span class='hs-varid'>x</span> <span class='hs-keyword'>of</span>
|
||||||
|
<a name="line-194"></a> <span class='hs-conid'>Left</span> <span class='hs-varid'>err</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>error</span> <span class='hs-varop'>$</span> <span class='hs-varid'>show</span> <span class='hs-varid'>err</span>
|
||||||
|
<a name="line-195"></a> <span class='hs-conid'>Right</span> <span class='hs-varid'>st</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>return</span> <span class='hs-varid'>st</span>
|
||||||
|
<a name="line-196"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>quoteDec</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>undefined</span>
|
||||||
|
<a name="line-197"></a> <span class='hs-layout'>}</span>
|
||||||
|
<a name="line-198"></a>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
116
src/Servant-Server.html
Normal file
116
src/Servant-Server.html
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant/Server.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
|
||||||
|
<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE OverloadedStrings #-}</span>
|
||||||
|
<a name="line-3"></a>
|
||||||
|
<a name="line-4"></a><span class='hs-comment'>-- | This module lets you implement 'Server's for defined APIs. You'll</span>
|
||||||
|
<a name="line-5"></a><span class='hs-comment'>-- most likely just need 'serve'.</span>
|
||||||
|
<a name="line-6"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-7"></a>
|
||||||
|
<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Monoid</span>
|
||||||
|
<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
|
||||||
|
<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>HTTP</span><span class='hs-varop'>.</span><span class='hs-conid'>Types</span>
|
||||||
|
<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
|
||||||
|
<a name="line-12"></a>
|
||||||
|
<a name="line-13"></a><span class='hs-comment'>-- * Implementing Servers</span>
|
||||||
|
<a name="line-14"></a>
|
||||||
|
<a name="line-15"></a><a name="serve"></a><span class='hs-comment'>-- | 'serve' allows you to implement an API and produce a wai 'Application'.</span>
|
||||||
|
<a name="line-16"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-17"></a><span class='hs-comment'>-- Example:</span>
|
||||||
|
<a name="line-18"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-19"></a><span class='hs-comment'>-- > type MyApi = "books" :> Get [Book] -- GET /books</span>
|
||||||
|
<a name="line-20"></a><span class='hs-comment'>-- > :<|> "books" :> ReqBody Book :> Post Book -- POST /books</span>
|
||||||
|
<a name="line-21"></a><span class='hs-comment'>-- ></span>
|
||||||
|
<a name="line-22"></a><span class='hs-comment'>-- > server :: Server MyApi</span>
|
||||||
|
<a name="line-23"></a><span class='hs-comment'>-- > server = listAllBooks :<|> postBook</span>
|
||||||
|
<a name="line-24"></a><span class='hs-comment'>-- > where listAllBooks = ...</span>
|
||||||
|
<a name="line-25"></a><span class='hs-comment'>-- > postBook book = ...</span>
|
||||||
|
<a name="line-26"></a><span class='hs-comment'>-- ></span>
|
||||||
|
<a name="line-27"></a><span class='hs-comment'>-- > app :: Application</span>
|
||||||
|
<a name="line-28"></a><span class='hs-comment'>-- > app = serve myApi server</span>
|
||||||
|
<a name="line-29"></a><span class='hs-comment'>-- ></span>
|
||||||
|
<a name="line-30"></a><span class='hs-comment'>-- > main :: IO ()</span>
|
||||||
|
<a name="line-31"></a><span class='hs-comment'>-- > main = Network.Wai.Handler.Warp.run 8080 app</span>
|
||||||
|
<a name="line-32"></a><span class='hs-definition'>serve</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>layout</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>layout</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Server</span> <span class='hs-varid'>layout</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Application</span>
|
||||||
|
<a name="line-33"></a><span class='hs-definition'>serve</span> <span class='hs-varid'>p</span> <span class='hs-varid'>server</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>toApplication</span> <span class='hs-layout'>(</span><span class='hs-varid'>route</span> <span class='hs-varid'>p</span> <span class='hs-varid'>server</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-34"></a>
|
||||||
|
<a name="line-35"></a><a name="toApplication"></a><span class='hs-definition'>toApplication</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RoutingApplication</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Application</span>
|
||||||
|
<a name="line-36"></a><span class='hs-definition'>toApplication</span> <span class='hs-varid'>ra</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
|
||||||
|
<a name="line-37"></a> <span class='hs-varid'>ra</span> <span class='hs-varid'>request</span> <span class='hs-layout'>(</span><span class='hs-varid'>routingRespond</span> <span class='hs-varop'>.</span> <span class='hs-varid'>routeResult</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-38"></a> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-39"></a> <span class='hs-varid'>routingRespond</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Either</span> <span class='hs-conid'>RouteMismatch</span> <span class='hs-conid'>Response</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>ResponseReceived</span>
|
||||||
|
<a name="line-40"></a> <span class='hs-varid'>routingRespond</span> <span class='hs-layout'>(</span><span class='hs-conid'>Left</span> <span class='hs-conid'>NotFound</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-41"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>responseLBS</span> <span class='hs-varid'>notFound404</span> <span class='hs-conid'>[]</span> <span class='hs-str'>"not found"</span>
|
||||||
|
<a name="line-42"></a> <span class='hs-varid'>routingRespond</span> <span class='hs-layout'>(</span><span class='hs-conid'>Left</span> <span class='hs-conid'>WrongMethod</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-43"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>responseLBS</span> <span class='hs-varid'>methodNotAllowed405</span> <span class='hs-conid'>[]</span> <span class='hs-str'>"method not allowed"</span>
|
||||||
|
<a name="line-44"></a> <span class='hs-varid'>routingRespond</span> <span class='hs-layout'>(</span><span class='hs-conid'>Left</span> <span class='hs-conid'>InvalidBody</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-45"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>responseLBS</span> <span class='hs-varid'>badRequest400</span> <span class='hs-conid'>[]</span> <span class='hs-str'>"Invalid JSON in request body"</span>
|
||||||
|
<a name="line-46"></a> <span class='hs-varid'>routingRespond</span> <span class='hs-layout'>(</span><span class='hs-conid'>Right</span> <span class='hs-varid'>response</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-47"></a> <span class='hs-varid'>respond</span> <span class='hs-varid'>response</span>
|
||||||
|
<a name="line-48"></a>
|
||||||
|
<a name="line-49"></a><a name="RouteMismatch"></a><span class='hs-comment'>-- * Route mismatch</span>
|
||||||
|
<a name="line-50"></a><a name="RouteMismatch"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>RouteMismatch</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-51"></a> <span class='hs-conid'>NotFound</span> <span class='hs-comment'>-- ^ the usual "not found" error</span>
|
||||||
|
<a name="line-52"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>WrongMethod</span> <span class='hs-comment'>-- ^ a more informative "you just got the HTTP method wrong" error</span>
|
||||||
|
<a name="line-53"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>InvalidBody</span> <span class='hs-comment'>-- ^ an even more informative "your json request body wasn't valid" error</span>
|
||||||
|
<a name="line-54"></a> <span class='hs-keyword'>deriving</span> <span class='hs-layout'>(</span><span class='hs-conid'>Eq</span><span class='hs-layout'>,</span> <span class='hs-conid'>Show</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-55"></a>
|
||||||
|
<a name="line-56"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- | </span>
|
||||||
|
<a name="line-57"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- @</span>
|
||||||
|
<a name="line-58"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- > mempty = NotFound</span>
|
||||||
|
<a name="line-59"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- ></span>
|
||||||
|
<a name="line-60"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- > NotFound `mappend` x = x</span>
|
||||||
|
<a name="line-61"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- > WrongMethod `mappend` InvalidBody = InvalidBody</span>
|
||||||
|
<a name="line-62"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- > WrongMethod `mappend` _ = WrongMethod</span>
|
||||||
|
<a name="line-63"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- > InvalidBody `mappend` _ = InvalidBody</span>
|
||||||
|
<a name="line-64"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- @</span>
|
||||||
|
<a name="line-65"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Monoid</span> <span class='hs-conid'>RouteMismatch</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-66"></a> <span class='hs-varid'>mempty</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NotFound</span>
|
||||||
|
<a name="line-67"></a>
|
||||||
|
<a name="line-68"></a> <span class='hs-conid'>NotFound</span> <span class='hs-varop'>`mappend`</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>x</span>
|
||||||
|
<a name="line-69"></a> <span class='hs-conid'>WrongMethod</span> <span class='hs-varop'>`mappend`</span> <span class='hs-conid'>InvalidBody</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>InvalidBody</span>
|
||||||
|
<a name="line-70"></a> <span class='hs-conid'>WrongMethod</span> <span class='hs-varop'>`mappend`</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>WrongMethod</span>
|
||||||
|
<a name="line-71"></a> <span class='hs-conid'>InvalidBody</span> <span class='hs-varop'>`mappend`</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>InvalidBody</span>
|
||||||
|
<a name="line-72"></a>
|
||||||
|
<a name="line-73"></a><a name="RouteResult"></a><span class='hs-comment'>-- | A wrapper around @'Either' 'RouteMismatch' a@.</span>
|
||||||
|
<a name="line-74"></a><a name="RouteResult"></a><span class='hs-keyword'>newtype</span> <span class='hs-conid'>RouteResult</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-75"></a> <span class='hs-conid'>RR</span> <span class='hs-layout'>{</span> <span class='hs-varid'>routeResult</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Either</span> <span class='hs-conid'>RouteMismatch</span> <span class='hs-varid'>a</span> <span class='hs-layout'>}</span>
|
||||||
|
<a name="line-76"></a> <span class='hs-keyword'>deriving</span> <span class='hs-layout'>(</span><span class='hs-conid'>Eq</span><span class='hs-layout'>,</span> <span class='hs-conid'>Show</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-77"></a>
|
||||||
|
<a name="line-78"></a><a name="failWith"></a><span class='hs-definition'>failWith</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RouteMismatch</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>RouteResult</span> <span class='hs-varid'>a</span>
|
||||||
|
<a name="line-79"></a><span class='hs-definition'>failWith</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>RR</span> <span class='hs-varop'>.</span> <span class='hs-conid'>Left</span>
|
||||||
|
<a name="line-80"></a>
|
||||||
|
<a name="line-81"></a><a name="succeedWith"></a><span class='hs-definition'>succeedWith</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>RouteResult</span> <span class='hs-varid'>a</span>
|
||||||
|
<a name="line-82"></a><span class='hs-definition'>succeedWith</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>RR</span> <span class='hs-varop'>.</span> <span class='hs-conid'>Right</span>
|
||||||
|
<a name="line-83"></a>
|
||||||
|
<a name="line-84"></a><a name="isMismatch"></a><span class='hs-definition'>isMismatch</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RouteResult</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Bool</span>
|
||||||
|
<a name="line-85"></a><span class='hs-definition'>isMismatch</span> <span class='hs-layout'>(</span><span class='hs-conid'>RR</span> <span class='hs-layout'>(</span><span class='hs-conid'>Left</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
|
||||||
|
<a name="line-86"></a><span class='hs-definition'>isMismatch</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
|
||||||
|
<a name="line-87"></a>
|
||||||
|
<a name="line-88"></a><a name="instance%20Monoid%20(RouteResult%20a)"></a><span class='hs-comment'>-- | If we get a `Right`, it has precedence over everything else.</span>
|
||||||
|
<a name="line-89"></a><a name="instance%20Monoid%20(RouteResult%20a)"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-90"></a><a name="instance%20Monoid%20(RouteResult%20a)"></a><span class='hs-comment'>-- This in particular means that if we could get several 'Right's,</span>
|
||||||
|
<a name="line-91"></a><a name="instance%20Monoid%20(RouteResult%20a)"></a><span class='hs-comment'>-- only the first we encounter would be taken into account.</span>
|
||||||
|
<a name="line-92"></a><a name="instance%20Monoid%20(RouteResult%20a)"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Monoid</span> <span class='hs-layout'>(</span><span class='hs-conid'>RouteResult</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-93"></a> <span class='hs-varid'>mempty</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>RR</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Left</span> <span class='hs-varid'>mempty</span>
|
||||||
|
<a name="line-94"></a>
|
||||||
|
<a name="line-95"></a> <span class='hs-conid'>RR</span> <span class='hs-layout'>(</span><span class='hs-conid'>Left</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-varop'>`mappend`</span> <span class='hs-conid'>RR</span> <span class='hs-layout'>(</span><span class='hs-conid'>Left</span> <span class='hs-varid'>y</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>RR</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Left</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span> <span class='hs-varop'><></span> <span class='hs-varid'>y</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-96"></a> <span class='hs-conid'>RR</span> <span class='hs-layout'>(</span><span class='hs-conid'>Left</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-varop'>`mappend`</span> <span class='hs-conid'>RR</span> <span class='hs-layout'>(</span><span class='hs-conid'>Right</span> <span class='hs-varid'>y</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>RR</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Right</span> <span class='hs-varid'>y</span>
|
||||||
|
<a name="line-97"></a> <span class='hs-varid'>r</span> <span class='hs-varop'>`mappend`</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>r</span>
|
||||||
|
<a name="line-98"></a>
|
||||||
|
<a name="line-99"></a><a name="RoutingApplication"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>RoutingApplication</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-100"></a> <span class='hs-conid'>Request</span> <span class='hs-comment'>-- ^ the request, the field 'pathInfo' may be modified by url routing</span>
|
||||||
|
<a name="line-101"></a> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>RouteResult</span> <span class='hs-conid'>Response</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>ResponseReceived</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>ResponseReceived</span>
|
||||||
|
<a name="line-102"></a>
|
||||||
|
<a name="line-103"></a><span class='hs-keyword'>class</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>layout</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-104"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-varid'>layout</span> <span class='hs-keyglyph'>::</span> <span class='hs-varop'>*</span>
|
||||||
|
<a name="line-105"></a> <span class='hs-varid'>route</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>layout</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Server</span> <span class='hs-varid'>layout</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>RoutingApplication</span>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
121
src/Servant-Utils-Links.html
Normal file
121
src/Servant-Utils-Links.html
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant/Utils/Links.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE PolyKinds #-}</span>
|
||||||
|
<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE DataKinds #-}</span>
|
||||||
|
<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE FlexibleInstances #-}</span>
|
||||||
|
<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
|
||||||
|
<a name="line-5"></a><span class='hs-comment'>{-# LANGUAGE TypeOperators #-}</span>
|
||||||
|
<a name="line-6"></a><span class='hs-comment'>{-# LANGUAGE FunctionalDependencies #-}</span>
|
||||||
|
<a name="line-7"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
|
||||||
|
<a name="line-8"></a><span class='hs-comment'>{-# LANGUAGE UndecidableInstances #-}</span>
|
||||||
|
<a name="line-9"></a><span class='hs-comment'>-- | Type safe internal links.</span>
|
||||||
|
<a name="line-10"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-11"></a><span class='hs-comment'>-- Provides the function 'mkLink':</span>
|
||||||
|
<a name="line-12"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-13"></a><span class='hs-comment'>-- @</span>
|
||||||
|
<a name="line-14"></a><span class='hs-comment'>-- type API = Proxy ("hello" :> Get Int</span>
|
||||||
|
<a name="line-15"></a><span class='hs-comment'>-- :<|> "bye" :> QueryParam "name" String :> Post Bool)</span>
|
||||||
|
<a name="line-16"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-17"></a><span class='hs-comment'>-- api :: API</span>
|
||||||
|
<a name="line-18"></a><span class='hs-comment'>-- api = proxy</span>
|
||||||
|
<a name="line-19"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-20"></a><span class='hs-comment'>-- link1 :: Proxy ("hello" :> Get Int)</span>
|
||||||
|
<a name="line-21"></a><span class='hs-comment'>-- link1 = proxy</span>
|
||||||
|
<a name="line-22"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-23"></a><span class='hs-comment'>-- link2 :: Proxy ("hello" :> Delete)</span>
|
||||||
|
<a name="line-24"></a><span class='hs-comment'>-- link2 = proxy</span>
|
||||||
|
<a name="line-25"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-26"></a><span class='hs-comment'>-- mkLink link1 API -- typechecks, returns 'Link "/hello"'</span>
|
||||||
|
<a name="line-27"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-28"></a><span class='hs-comment'>-- mkLink link2 API -- doesn't typecheck</span>
|
||||||
|
<a name="line-29"></a><span class='hs-comment'>-- @</span>
|
||||||
|
<a name="line-30"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-31"></a><span class='hs-comment'>-- That is, 'mkLink' takes two arguments, a link proxy and a sitemap, and</span>
|
||||||
|
<a name="line-32"></a><span class='hs-comment'>-- returns a 'Link', but only typechecks if the link proxy is a valid link,</span>
|
||||||
|
<a name="line-33"></a><span class='hs-comment'>-- and part of the sitemap.</span>
|
||||||
|
<a name="line-34"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-35"></a><span class='hs-comment'>-- __N.B.:__ 'mkLink' assumes a capture matches any string (without slashes).</span>
|
||||||
|
<a name="line-36"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>Links</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-37"></a>
|
||||||
|
<a name="line-38"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
|
||||||
|
<a name="line-39"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>TypeLits</span>
|
||||||
|
<a name="line-40"></a>
|
||||||
|
<a name="line-41"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Capture</span>
|
||||||
|
<a name="line-42"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>ReqBody</span>
|
||||||
|
<a name="line-43"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>QueryParam</span>
|
||||||
|
<a name="line-44"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Get</span>
|
||||||
|
<a name="line-45"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Post</span>
|
||||||
|
<a name="line-46"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Put</span>
|
||||||
|
<a name="line-47"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Delete</span>
|
||||||
|
<a name="line-48"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Sub</span>
|
||||||
|
<a name="line-49"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Alternative</span>
|
||||||
|
<a name="line-50"></a>
|
||||||
|
<a name="line-51"></a>
|
||||||
|
<a name="line-52"></a><span class='hs-keyword'>type</span> <span class='hs-varid'>family</span> <span class='hs-conid'>Or</span> <span class='hs-varid'>a</span> <span class='hs-varid'>b</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-53"></a> <span class='hs-conid'>Or</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span>
|
||||||
|
<a name="line-54"></a> <span class='hs-conid'>Or</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span>
|
||||||
|
<a name="line-55"></a> <span class='hs-conid'>Or</span> <span class='hs-varid'>a</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span>
|
||||||
|
<a name="line-56"></a>
|
||||||
|
<a name="line-57"></a><span class='hs-keyword'>type</span> <span class='hs-varid'>family</span> <span class='hs-conid'>And</span> <span class='hs-varid'>a</span> <span class='hs-varid'>b</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-58"></a> <span class='hs-conid'>And</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span>
|
||||||
|
<a name="line-59"></a> <span class='hs-conid'>And</span> <span class='hs-varid'>a</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span>
|
||||||
|
<a name="line-60"></a> <span class='hs-conid'>And</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span>
|
||||||
|
<a name="line-61"></a>
|
||||||
|
<a name="line-62"></a><span class='hs-keyword'>type</span> <span class='hs-varid'>family</span> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-63"></a> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>e</span> <span class='hs-layout'>(</span><span class='hs-varid'>sa</span> <span class='hs-conop'>:<|></span> <span class='hs-varid'>sb</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Or</span> <span class='hs-layout'>(</span><span class='hs-conid'>IsElem</span> <span class='hs-varid'>e</span> <span class='hs-varid'>sa</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>IsElem</span> <span class='hs-varid'>e</span> <span class='hs-varid'>sb</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-64"></a> <span class='hs-conid'>IsElem</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sa</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sb</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>sa</span> <span class='hs-varid'>sb</span>
|
||||||
|
<a name="line-65"></a> <span class='hs-conid'>IsElem</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sa</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>Capture</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sb</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>sa</span> <span class='hs-varid'>sb</span>
|
||||||
|
<a name="line-66"></a> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>sa</span> <span class='hs-layout'>(</span><span class='hs-conid'>ReqBody</span> <span class='hs-varid'>x</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sb</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>sa</span> <span class='hs-varid'>sb</span>
|
||||||
|
<a name="line-67"></a> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>sa</span> <span class='hs-layout'>(</span><span class='hs-conid'>QueryParam</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-conop'>:></span> <span class='hs-varid'>sb</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>sa</span> <span class='hs-varid'>sb</span>
|
||||||
|
<a name="line-68"></a> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>e</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span>
|
||||||
|
<a name="line-69"></a> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>e</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span>
|
||||||
|
<a name="line-70"></a>
|
||||||
|
<a name="line-71"></a><span class='hs-keyword'>type</span> <span class='hs-varid'>family</span> <span class='hs-conid'>IsLink''</span> <span class='hs-varid'>l</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-72"></a> <span class='hs-conid'>IsLink''</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span> <span class='hs-conop'>:></span> <span class='hs-conid'>Get</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IsLink'</span> <span class='hs-varid'>e</span>
|
||||||
|
<a name="line-73"></a> <span class='hs-conid'>IsLink''</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span> <span class='hs-conop'>:></span> <span class='hs-conid'>Post</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IsLink'</span> <span class='hs-varid'>e</span>
|
||||||
|
<a name="line-74"></a> <span class='hs-conid'>IsLink''</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span> <span class='hs-conop'>:></span> <span class='hs-conid'>Put</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IsLink'</span> <span class='hs-varid'>e</span>
|
||||||
|
<a name="line-75"></a> <span class='hs-conid'>IsLink''</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span> <span class='hs-conop'>:></span> <span class='hs-conid'>Delete</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IsLink'</span> <span class='hs-varid'>e</span>
|
||||||
|
<a name="line-76"></a> <span class='hs-conid'>IsLink''</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span>
|
||||||
|
<a name="line-77"></a>
|
||||||
|
<a name="line-78"></a><span class='hs-keyword'>type</span> <span class='hs-varid'>family</span> <span class='hs-conid'>IsLink'</span> <span class='hs-varid'>e</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-79"></a> <span class='hs-conid'>IsLink'</span> <span class='hs-layout'>(</span><span class='hs-varid'>f</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Symbol</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span>
|
||||||
|
<a name="line-80"></a>
|
||||||
|
<a name="line-81"></a><span class='hs-keyword'>type</span> <span class='hs-varid'>family</span> <span class='hs-conid'>IsLink</span> <span class='hs-varid'>e</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-82"></a> <span class='hs-conid'>IsLink</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-conop'>:></span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Or</span> <span class='hs-layout'>(</span><span class='hs-conid'>And</span> <span class='hs-layout'>(</span><span class='hs-conid'>IsLink'</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>IsLink''</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-83"></a> <span class='hs-layout'>(</span><span class='hs-conid'>IsLink''</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-conop'>:></span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-84"></a>
|
||||||
|
<a name="line-85"></a>
|
||||||
|
<a name="line-86"></a><a name="ValidLinkIn"></a><span class='hs-comment'>-- | The 'ValidLinkIn f s' constraint holds when 's' is an API that</span>
|
||||||
|
<a name="line-87"></a><a name="ValidLinkIn"></a><span class='hs-comment'>-- contains 'f', and 'f' is a link.</span>
|
||||||
|
<a name="line-88"></a><a name="ValidLinkIn"></a><span class='hs-keyword'>class</span> <span class='hs-conid'>ValidLinkIn</span> <span class='hs-varid'>f</span> <span class='hs-varid'>s</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-89"></a> <span class='hs-varid'>mkLink</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Link</span> <span class='hs-comment'>-- ^ This function will only typecheck if `f`</span>
|
||||||
|
<a name="line-90"></a> <span class='hs-comment'>-- is an URI within `s`</span>
|
||||||
|
<a name="line-91"></a>
|
||||||
|
<a name="line-92"></a><a name="instance%20ValidLinkIn%20f%20s"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>f</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>~</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span>
|
||||||
|
<a name="line-93"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>IsLink</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>~</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span>
|
||||||
|
<a name="line-94"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>VLinkHelper</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>ValidLinkIn</span> <span class='hs-varid'>f</span> <span class='hs-varid'>s</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-95"></a> <span class='hs-varid'>mkLink</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Link</span> <span class='hs-layout'>(</span><span class='hs-varid'>vlh</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-96"></a>
|
||||||
|
<a name="line-97"></a><a name="Link"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Link</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Link</span> <span class='hs-conid'>String</span> <span class='hs-keyword'>deriving</span> <span class='hs-conid'>Show</span>
|
||||||
|
<a name="line-98"></a>
|
||||||
|
<a name="line-99"></a><a name="VLinkHelper"></a><span class='hs-keyword'>class</span> <span class='hs-conid'>VLinkHelper</span> <span class='hs-varid'>f</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-100"></a> <span class='hs-varid'>vlh</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyword'>forall</span> <span class='hs-varid'>proxy</span><span class='hs-varop'>.</span> <span class='hs-varid'>proxy</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>String</span>
|
||||||
|
<a name="line-101"></a>
|
||||||
|
<a name="line-102"></a><a name="instance%20VLinkHelper%20(s%20:%3e%20e)"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>KnownSymbol</span> <span class='hs-varid'>s</span><span class='hs-layout'>,</span> <span class='hs-conid'>VLinkHelper</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>VLinkHelper</span> <span class='hs-layout'>(</span><span class='hs-varid'>s</span> <span class='hs-conop'>:></span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-103"></a> <span class='hs-varid'>vlh</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-str'>"/"</span> <span class='hs-varop'>++</span> <span class='hs-varid'>symbolVal</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-varop'>++</span> <span class='hs-varid'>vlh</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-104"></a>
|
||||||
|
<a name="line-105"></a><a name="instance%20VLinkHelper%20(Get%20x)"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>VLinkHelper</span> <span class='hs-layout'>(</span><span class='hs-conid'>Get</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-106"></a> <span class='hs-varid'>vlh</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-str'>""</span>
|
||||||
|
<a name="line-107"></a>
|
||||||
|
<a name="line-108"></a><a name="instance%20VLinkHelper%20(Post%20x)"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>VLinkHelper</span> <span class='hs-layout'>(</span><span class='hs-conid'>Post</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-109"></a> <span class='hs-varid'>vlh</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-str'>""</span>
|
||||||
|
<a name="line-110"></a>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
47
src/Servant-Utils-StaticFiles.html
Normal file
47
src/Servant-Utils-StaticFiles.html
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant/Utils/StaticFiles.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-comment'>-- | This module defines a sever-side handler that lets you serve static files.</span>
|
||||||
|
<a name="line-2"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-3"></a><span class='hs-comment'>-- - 'serveDirectory' lets you serve anything that lives under a particular</span>
|
||||||
|
<a name="line-4"></a><span class='hs-comment'>-- directory on your filesystem.</span>
|
||||||
|
<a name="line-5"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>StaticFiles</span> <span class='hs-layout'>(</span>
|
||||||
|
<a name="line-6"></a> <span class='hs-varid'>serveDirectory</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-7"></a> <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-8"></a>
|
||||||
|
<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Filesystem</span><span class='hs-varop'>.</span><span class='hs-conid'>Path</span><span class='hs-varop'>.</span><span class='hs-conid'>CurrentOS</span> <span class='hs-layout'>(</span><span class='hs-varid'>decodeString</span><span class='hs-layout'>)</span>
|
||||||
|
<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span><span class='hs-varop'>.</span><span class='hs-conid'>Application</span><span class='hs-varop'>.</span><span class='hs-conid'>Static</span>
|
||||||
|
<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Raw</span>
|
||||||
|
<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
|
||||||
|
<a name="line-13"></a>
|
||||||
|
<a name="line-14"></a><a name="serveDirectory"></a><span class='hs-comment'>-- | Serve anything under the specified directory as a 'Raw' endpoint.</span>
|
||||||
|
<a name="line-15"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-16"></a><span class='hs-comment'>-- @</span>
|
||||||
|
<a name="line-17"></a><span class='hs-comment'>-- type MyApi = "static" :> Raw</span>
|
||||||
|
<a name="line-18"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-19"></a><span class='hs-comment'>-- server :: Server MyApi</span>
|
||||||
|
<a name="line-20"></a><span class='hs-comment'>-- server = serveDirectory "\/var\/www"</span>
|
||||||
|
<a name="line-21"></a><span class='hs-comment'>-- @</span>
|
||||||
|
<a name="line-22"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-23"></a><span class='hs-comment'>-- would capture any request to @\/static\/\<something>@ and look for</span>
|
||||||
|
<a name="line-24"></a><span class='hs-comment'>-- @\<something>@ under @\/var\/www@.</span>
|
||||||
|
<a name="line-25"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-26"></a><span class='hs-comment'>-- It will do its best to guess the MIME type for that file, based on the extension,</span>
|
||||||
|
<a name="line-27"></a><span class='hs-comment'>-- and send an appropriate /Content-Type/ header if possible.</span>
|
||||||
|
<a name="line-28"></a><span class='hs-comment'>--</span>
|
||||||
|
<a name="line-29"></a><span class='hs-comment'>-- If your goal is to serve HTML, CSS and Javascript files that use the rest of the API</span>
|
||||||
|
<a name="line-30"></a><span class='hs-comment'>-- as a webapp backend, you will most likely not want the static files to be hidden</span>
|
||||||
|
<a name="line-31"></a><span class='hs-comment'>-- behind a /\/static\// prefix. In that case, remember to put the 'serveDirectory'</span>
|
||||||
|
<a name="line-32"></a><span class='hs-comment'>-- handler in the last position, because /servant/ will try to match the handlers</span>
|
||||||
|
<a name="line-33"></a><span class='hs-comment'>-- in order.</span>
|
||||||
|
<a name="line-34"></a><span class='hs-definition'>serveDirectory</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FilePath</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Server</span> <span class='hs-conid'>Raw</span>
|
||||||
|
<a name="line-35"></a><span class='hs-definition'>serveDirectory</span> <span class='hs-varid'>documentRoot</span> <span class='hs-keyglyph'>=</span>
|
||||||
|
<a name="line-36"></a> <span class='hs-varid'>staticApp</span> <span class='hs-layout'>(</span><span class='hs-varid'>defaultFileServerSettings</span> <span class='hs-layout'>(</span><span class='hs-varid'>decodeString</span> <span class='hs-layout'>(</span><span class='hs-varid'>documentRoot</span> <span class='hs-varop'>++</span> <span class='hs-str'>"/"</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
35
src/Servant.html
Normal file
35
src/Servant.html
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
|
||||||
|
<title>src/Servant.hs</title>
|
||||||
|
<link type='text/css' rel='stylesheet' href='hscolour.css' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre><a name="line-1"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span> <span class='hs-layout'>(</span>
|
||||||
|
<a name="line-2"></a> <span class='hs-comment'>-- | This module and its submodules can be used to define servant APIs. Note</span>
|
||||||
|
<a name="line-3"></a> <span class='hs-comment'>-- that these API definitions don't directly implement a server (or anything</span>
|
||||||
|
<a name="line-4"></a> <span class='hs-comment'>-- else).</span>
|
||||||
|
<a name="line-5"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-6"></a> <span class='hs-comment'>-- | For implementing servers for servant APIs.</span>
|
||||||
|
<a name="line-7"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-8"></a> <span class='hs-comment'>-- | Using your types in request paths and query string parameters</span>
|
||||||
|
<a name="line-9"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Common</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-10"></a> <span class='hs-comment'>-- | Utilities on top of the servant core</span>
|
||||||
|
<a name="line-11"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>QQ</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-12"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>Links</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-13"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>StaticFiles</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-14"></a> <span class='hs-comment'>-- | Useful re-exports</span>
|
||||||
|
<a name="line-15"></a> <span class='hs-conid'>Proxy</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
|
||||||
|
<a name="line-16"></a> <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
|
||||||
|
<a name="line-17"></a>
|
||||||
|
<a name="line-18"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
|
||||||
|
<a name="line-19"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span>
|
||||||
|
<a name="line-20"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Common</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span>
|
||||||
|
<a name="line-21"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
|
||||||
|
<a name="line-22"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>QQ</span>
|
||||||
|
<a name="line-23"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>Links</span>
|
||||||
|
<a name="line-24"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>StaticFiles</span>
|
||||||
|
</pre></body>
|
||||||
|
</html>
|
5
src/hscolour.css
Normal file
5
src/hscolour.css
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.hs-keyglyph, .hs-layout {color: red;}
|
||||||
|
.hs-keyword {color: blue;}
|
||||||
|
.hs-comment, .hs-comment a {color: green;}
|
||||||
|
.hs-str, .hs-chr {color: teal;}
|
||||||
|
.hs-keyword, .hs-conid, .hs-varid, .hs-conop, .hs-varop, .hs-num, .hs-cpp, .hs-sel, .hs-definition {}
|
BIN
synopsis.png
Normal file
BIN
synopsis.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
Loading…
Reference in a new issue