Fix cabal file, stack.yaml, and sources.txt

This commit is contained in:
Julian K. Arni 2016-01-27 22:46:28 +01:00
parent 45d034f137
commit b1791022dc
8 changed files with 41 additions and 45 deletions

View file

@ -1,7 +1,4 @@
--- # A web API as a type
title: A web API as a type
toc: true
---
The source for this tutorial section is a literate haskell file, so first we The source for this tutorial section is a literate haskell file, so first we
need to have some language extensions and imports: need to have some language extensions and imports:
@ -25,8 +22,7 @@ Consider the following informal specification of an API:
You *should* be able to formalize that. And then use the formalized version to You *should* be able to formalize that. And then use the formalized version to
get you much of the way towards writing a web app. And all the way towards get you much of the way towards writing a web app. And all the way towards
getting some client libraries, and documentation (and in the future, who knows getting some client libraries, and documentation, and more.
- tests, HATEOAS, ...).
How would we describe it with servant? As mentioned earlier, an endpoint How would we describe it with servant? As mentioned earlier, an endpoint
description is a good old Haskell **type**: description is a good old Haskell **type**:
@ -45,8 +41,8 @@ data User = User {
Let's break that down: Let's break that down:
- `"users"` says that our endpoint will be accessible under `/users`; - `"users"` says that our endpoint will be accessible under `/users`;
- `QueryParam "sortby" SortBy`, where `SortBy` is defined by `data SortBy = Age - `QueryParam "sortby" SortBy`, where `SortBy` is defined by `data SortBy = Age | Name`,
| Name`, says that the endpoint has a query string parameter named `sortby` says that the endpoint has a query string parameter named `sortby`
whose value will be extracted as a value of type `SortBy`. whose value will be extracted as a value of type `SortBy`.
- `Get '[JSON] [User]` says that the endpoint will be accessible through HTTP - `Get '[JSON] [User]` says that the endpoint will be accessible through HTTP
GET requests, returning a list of users encoded as JSON. You will see GET requests, returning a list of users encoded as JSON. You will see
@ -54,7 +50,7 @@ later how you can make use of this to make your data available under different
formats, the choice being made depending on the [Accept formats, the choice being made depending on the [Accept
header](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html) specified in header](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html) specified in
the client's request. the client's request.
- the `:>` operator that separates the various "combinators" just lets you - The `:>` operator that separates the various "combinators" just lets you
sequence static path fragments, URL captures and other combinators. The sequence static path fragments, URL captures and other combinators. The
ordering only matters for static path fragments and URL captures. `"users" :> ordering only matters for static path fragments and URL captures. `"users" :>
"list-all" :> Get '[JSON] [User]`, equivalent to `/users/list-all`, is "list-all" :> Get '[JSON] [User]`, equivalent to `/users/list-all`, is
@ -74,11 +70,10 @@ type UserAPI2 = "users" :> "list-all" :> Get '[JSON] [User]
always write your own when you need it. Here's a quick overview of all the always write your own when you need it. Here's a quick overview of all the
combinators that servant comes with. combinators that servant comes with.
Combinators ## Combinators
===========
### Static strings
Static strings
--------------
As you've already seen, you can use type-level strings (enabled with the As you've already seen, you can use type-level strings (enabled with the
`DataKinds` language extension) for static path fragments. Chaining `DataKinds` language extension) for static path fragments. Chaining
@ -90,8 +85,8 @@ type UserAPI3 = "users" :> "list-all" :> "now" :> Get '[JSON] [User]
-- /users/list-all/now -- /users/list-all/now
``` ```
`Delete`, `Get`, `Patch`, `Post` and `Put` ### `Delete`, `Get`, `Patch`, `Post` and `Put`
------------------------------------------
These 5 combinators are very similar except that they each describe a These 5 combinators are very similar except that they each describe a
different HTTP method. This is how they're declared different HTTP method. This is how they're declared
@ -112,8 +107,8 @@ type UserAPI4 = "users" :> Get '[JSON] [User]
:<|> "admins" :> Get '[JSON] [User] :<|> "admins" :> Get '[JSON] [User]
``` ```
`Capture` ### `Capture`
---------
URL captures are parts of the URL that are variable and whose actual value is URL captures are parts of the URL that are variable and whose actual value is
captured and passed to the request handlers. In many web frameworks, you'll see captured and passed to the request handlers. In many web frameworks, you'll see
@ -147,8 +142,7 @@ type UserAPI5 = "user" :> Capture "userid" Integer :> Get '[JSON] User
-- equivalent to 'DELETE /user/:userid' -- equivalent to 'DELETE /user/:userid'
``` ```
`QueryParam`, `QueryParams`, `QueryFlag`, `MatrixParam`, `MatrixParams` and `MatrixFlag` ### `QueryParam`, `QueryParams`, `QueryFlag`, `MatrixParam`, `MatrixParams` and `MatrixFlag`
----------------------------------------------------------------------------------------
`QueryParam`, `QueryParams` and `QueryFlag` are about query string `QueryParam`, `QueryParams` and `QueryFlag` are about query string
parameters, i.e., those parameters that come after the question mark parameters, i.e., those parameters that come after the question mark
@ -202,8 +196,7 @@ type UserAPI6 = "users" :> QueryParam "sortby" SortBy :> Get '[JSON] [User]
Again, your handlers don't have to deserialize these things (into, for example, Again, your handlers don't have to deserialize these things (into, for example,
a `SortBy`). *servant* takes care of it. a `SortBy`). *servant* takes care of it.
`ReqBody` ### `ReqBody`
---------
Each HTTP request can carry some additional data that the server can use in its Each HTTP request can carry some additional data that the server can use in its
*body*, and this data can be encoded in any format -- as long as the server *body*, and this data can be encoded in any format -- as long as the server
@ -240,8 +233,8 @@ type UserAPI7 = "users" :> ReqBody '[JSON] User :> Post '[JSON] User
-- - returns a User encoded in JSON -- - returns a User encoded in JSON
``` ```
Request `Header`s ### Request `Header`s
-----------------
Request headers are used for various purposes, from caching to carrying Request headers are used for various purposes, from caching to carrying
auth-related data. They consist of a header name and an associated value. An auth-related data. They consist of a header name and an associated value. An
@ -263,8 +256,7 @@ the client to send the request.
type UserAPI8 = "users" :> Header "User-Agent" Text :> Get '[JSON] [User] type UserAPI8 = "users" :> Header "User-Agent" Text :> Get '[JSON] [User]
``` ```
Content types ### Content types
-------------
So far, whenever we have used a combinator that carries a list of content So far, whenever we have used a combinator that carries a list of content
types, we've always specified `'[JSON]`. However, *servant* lets you use several types, we've always specified `'[JSON]`. However, *servant* lets you use several
@ -286,8 +278,7 @@ that everyone uses, we decided to release 2 packages, *servant-lucid* and
We will further explain how these content types and your data types can play We will further explain how these content types and your data types can play
together in the [section about serving an API](/tutorial/server.html). together in the [section about serving an API](/tutorial/server.html).
Response `Headers` ### Response `Headers`
------------------
Just like an HTTP request, the response generated by a webserver can carry Just like an HTTP request, the response generated by a webserver can carry
headers too. *servant* provides a `Headers` combinator that carries a list of headers too. *servant* provides a `Headers` combinator that carries a list of
@ -305,8 +296,7 @@ response, you could write it as below:
type UserAPI10 = "users" :> Get '[JSON] (Headers '[Header "User-Count" Integer] [User]) type UserAPI10 = "users" :> Get '[JSON] (Headers '[Header "User-Count" Integer] [User])
``` ```
Interoperability with other WAI `Application`s: `Raw` ### Interoperability with other WAI `Application`s: `Raw`
-----------------------------------------------------
Finally, we also include a combinator named `Raw` that can be used for two reasons: Finally, we also include a combinator named `Raw` that can be used for two reasons:

View file

@ -1,5 +1,5 @@
name: tutorial name: tutorial
version: 0.1.0.0 version: 0.5
synopsis: The servant tutorial synopsis: The servant tutorial
-- description: -- description:
homepage: http://haskell-servant.github.io/ homepage: http://haskell-servant.github.io/
@ -14,9 +14,16 @@ build-type: Simple
cabal-version: >=1.10 cabal-version: >=1.10
library library
exposed-modules: api-type.lhs exposed-modules: ApiType
, Client
, Docs
, Javascript
, Server
-- other-modules: -- other-modules:
-- other-extensions: -- other-extensions:
build-depends: base >=4.8 && <4.9 build-depends: base >=4.8 && <4.9
, text
, servant
-- hs-source-dirs: -- hs-source-dirs:
default-language: Haskell2010 default-language: Haskell2010
ghc-options: -Wall -Werror -c -pgmL markdown-unlit

View file

@ -5,7 +5,6 @@ servant-docs
servant-foreign servant-foreign
servant-js servant-js
servant-server servant-server
servant-examples
servant-blaze servant-blaze
servant-lucid servant-lucid
servant-mock servant-mock

View file

@ -7,12 +7,12 @@ packages:
- servant-cassava/ - servant-cassava/
- servant-client/ - servant-client/
- servant-docs/ - servant-docs/
- servant-examples/
- servant-foreign/ - servant-foreign/
- servant-js/ - servant-js/
- servant-lucid/ - servant-lucid/
- servant-mock/ - servant-mock/
- servant-server/ - servant-server/
- doc/tutorial
extra-deps: extra-deps:
- engine-io-wai-1.0.2 - engine-io-wai-1.0.2
- control-monad-omega-0.3.1 - control-monad-omega-0.3.1