git.iko.soy/typeable/servant
on master help sign in
Merge pull request #77 from haskell-servant/update-examples

Update examples for servant-docs and servant-client

commit955261ddd39fd5f384295588698de0e7f73dae59 authorChristian Marie <christian@ponies.io> dateFri 15 May 2015, 20:36 (11 years ago) parent13a881328647c0
4 files changed+63−50
servant-client/README.md+6−5 servant-client/src/Servant/Client.hs+51−40 servant-docs/README.md+2−2 servant-docs/src/Servant/Docs.hs+4−3
servant-client/README.md+6−5
@@ -7,14 +7,15 @@ This library lets you automatically derive Haskell functions that let you query
77## Example
88
99``` haskell
10−type MyApi = "books" :> Get [Book] -- GET /books
11− :<|> "books" :> ReqBody Book :> Post Book -- POST /books
10+type MyApi = "books" :> Get '[JSON] [Book] -- GET /books
11+ :<|> "books" :> ReqBody Book :> Post '[JSON] Book -- POST /books
1212
1313myApi :: Proxy MyApi
1414myApi = Proxy
1515
16−getAllBooks :: BaseUrl -> EitherT String IO [Book]
17−postNewBook :: Book -> BaseUrl -> EitherT String IO Book
16+getAllBooks :: EitherT String IO [Book]
17+postNewBook :: Book -> EitherT String IO Book
1818-- 'client' allows you to produce operations to query an API from a client.
19−(getAllBooks :<|> postNewBook) = client myApi
19+(getAllBooks :<|> postNewBook) = client myApi host
20+ where host = BaseUrl Http "localhost" 8080
2021```
servant-client/src/Servant/Client.hs+51−40
@@ -43,15 +43,16 @@ import Servant.Common.Req
4343
4444-- | 'client' allows you to produce operations to query an API from a client.
4545--
46−-- > type MyApi = "books" :> Get [Book] -- GET /books
47−-- > :<|> "books" :> ReqBody Book :> Post Book -- POST /books
46+-- > type MyApi = "books" :> Get '[JSON] [Book] -- GET /books
47+-- > :<|> "books" :> ReqBody '[JSON] Book :> Post Book -- POST /books
4848-- >
4949-- > myApi :: Proxy MyApi
5050-- > myApi = Proxy
5151-- >
52−-- > getAllBooks :: BaseUrl -> EitherT String IO [Book]
53−-- > postNewBook :: Book -> BaseUrl -> EitherT String IO Book
54−-- > (getAllBooks :<|> postNewBook) = client myApi
52+-- > getAllBooks :: EitherT String IO [Book]
53+-- > postNewBook :: Book -> EitherT String IO Book
54+-- > (getAllBooks :<|> postNewBook) = client myApi host
55+-- > where host = BaseUrl Http "localhost" 8080
5556client :: HasClient layout => Proxy layout -> BaseUrl -> Client layout
5657client p baseurl = clientWithRoute p defReq baseurl
5758
@@ -68,15 +69,16 @@ class HasClient layout where
6869-- one function for querying @a@ and another one for querying @b@,
6970-- stitching them together with ':<|>', which really is just like a pair.
7071--
71−-- > type MyApi = "books" :> Get [Book] -- GET /books
72−-- > :<|> "books" :> ReqBody Book :> Post Book -- POST /books
72+-- > type MyApi = "books" :> Get '[JSON] [Book] -- GET /books
73+-- > :<|> "books" :> ReqBody '[JSON] Book :> Post Book -- POST /books
7374-- >
7475-- > myApi :: Proxy MyApi
7576-- > myApi = Proxy
7677-- >
77−-- > getAllBooks :: BaseUrl -> EitherT String IO [Book]
78−-- > postNewBook :: Book -> BaseUrl -> EitherT String IO Book
79−-- > (getAllBooks :<|> postNewBook) = client myApi
78+-- > getAllBooks :: EitherT String IO [Book]
79+-- > postNewBook :: Book -> EitherT String IO Book
80+-- > (getAllBooks :<|> postNewBook) = client myApi host
81+-- > where host = BaseUrl Http "localhost" 8080
8082instance (HasClient a, HasClient b) => HasClient (a :<|> b) where
8183 type Client (a :<|> b) = Client a :<|> Client b
8284 clientWithRoute Proxy req baseurl =
@@ -94,13 +96,14 @@ instance (HasClient a, HasClient b) => HasClient (a :<|> b) where
9496--
9597-- Example:
9698--
97−-- > type MyApi = "books" :> Capture "isbn" Text :> Get Book
99+-- > type MyApi = "books" :> Capture "isbn" Text :> Get '[JSON] Book
98100-- >
99101-- > myApi :: Proxy MyApi
100102-- > myApi = Proxy
101103-- >
102−-- > getBook :: Text -> BaseUrl -> EitherT String IO Book
103−-- > getBook = client myApi
104+-- > getBook :: Text -> EitherT String IO Book
105+-- > getBook = client myApi host
106+-- > where host = BaseUrl Http "localhost" 8080
104107-- > -- then you can just use "getBook" to query that endpoint
105108instance (KnownSymbol capture, ToText a, HasClient sublayout)
106109 => HasClient (Capture capture a :> sublayout) where
@@ -205,19 +208,20 @@ instance
205208--
206209-- Example:
207210--
208−-- > newtype Referer = Referer Text
209−-- > deriving (Eq, Show, FromText, ToText)
211+-- > newtype Referer = Referer { referrer :: Text }
212+-- > deriving (Eq, Show, Generic, FromText, ToText)
210213-- >
211214-- > -- GET /view-my-referer
212−-- > type MyApi = "view-my-referer" :> Header "Referer" Referer :> Get Referer
215+-- > type MyApi = "view-my-referer" :> Header "Referer" Referer :> Get '[JSON] Referer
213216-- >
214217-- > myApi :: Proxy MyApi
215218-- > myApi = Proxy
216219-- >
217−-- > viewReferer :: Maybe Referer -> BaseUrl -> EitherT String IO Book
218−-- > viewReferer = client myApi
220+-- > viewReferer :: Maybe Referer -> EitherT String IO Book
221+-- > viewReferer = client myApi host
222+-- > where host = BaseUrl Http "localhost" 8080
219223-- > -- then you can just use "viewRefer" to query that endpoint
220−-- > -- specifying Nothing or Just "http://haskell.org/" as arguments
224+-- > -- specifying Nothing or e.g Just "http://haskell.org/" as arguments
221225instance (KnownSymbol sym, ToText a, HasClient sublayout)
222226 => HasClient (Header sym a :> sublayout) where
223227
@@ -366,13 +370,14 @@ instance
366370--
367371-- Example:
368372--
369−-- > type MyApi = "books" :> QueryParam "author" Text :> Get [Book]
373+-- > type MyApi = "books" :> QueryParam "author" Text :> Get '[JSON] [Book]
370374-- >
371375-- > myApi :: Proxy MyApi
372376-- > myApi = Proxy
373377-- >
374−-- > getBooksBy :: Maybe Text -> BaseUrl -> EitherT String IO [Book]
375−-- > getBooksBy = client myApi
378+-- > getBooksBy :: Maybe Text -> EitherT String IO [Book]
379+-- > getBooksBy = client myApi host
380+-- > where host = BaseUrl Http "localhost" 8080
376381-- > -- then you can just use "getBooksBy" to query that endpoint.
377382-- > -- 'getBooksBy Nothing' for all books
378383-- > -- 'getBooksBy (Just "Isaac Asimov")' to get all books by Isaac Asimov
@@ -411,13 +416,14 @@ instance (KnownSymbol sym, ToText a, HasClient sublayout)
411416--
412417-- Example:
413418--
414−-- > type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]
419+-- > type MyApi = "books" :> QueryParams "authors" Text :> Get '[JSON] [Book]
415420-- >
416421-- > myApi :: Proxy MyApi
417422-- > myApi = Proxy
418423-- >
419−-- > getBooksBy :: [Text] -> BaseUrl -> EitherT String IO [Book]
420−-- > getBooksBy = client myApi
424+-- > getBooksBy :: [Text] -> EitherT String IO [Book]
425+-- > getBooksBy = client myApi host
426+-- > where host = BaseUrl Http "localhost" 8080
421427-- > -- then you can just use "getBooksBy" to query that endpoint.
422428-- > -- 'getBooksBy []' for all books
423429-- > -- 'getBooksBy ["Isaac Asimov", "Robert A. Heinlein"]'
@@ -451,13 +457,14 @@ instance (KnownSymbol sym, ToText a, HasClient sublayout)
451457--
452458-- Example:
453459--
454−-- > type MyApi = "books" :> QueryFlag "published" :> Get [Book]
460+-- > type MyApi = "books" :> QueryFlag "published" :> Get '[JSON] [Book]
455461-- >
456462-- > myApi :: Proxy MyApi
457463-- > myApi = Proxy
458464-- >
459−-- > getBooks :: Bool -> BaseUrl -> EitherT String IO [Book]
460−-- > getBooks = client myApi
465+-- > getBooks :: Bool -> EitherT String IO [Book]
466+-- > getBooks = client myApi host
467+-- > where host = BaseUrl Http "localhost" 8080
461468-- > -- then you can just use "getBooks" to query that endpoint.
462469-- > -- 'getBooksBy False' for all books
463470-- > -- 'getBooksBy True' to only get _already published_ books
@@ -492,13 +499,14 @@ instance (KnownSymbol sym, HasClient sublayout)
492499--
493500-- Example:
494501--
495−-- > type MyApi = "books" :> MatrixParam "author" Text :> Get [Book]
502+-- > type MyApi = "books" :> MatrixParam "author" Text :> Get '[JSON] [Book]
496503-- >
497504-- > myApi :: Proxy MyApi
498505-- > myApi = Proxy
499506-- >
500−-- > getBooksBy :: Maybe Text -> BaseUrl -> EitherT String IO [Book]
501−-- > getBooksBy = client myApi
507+-- > getBooksBy :: Maybe Text -> EitherT String IO [Book]
508+-- > getBooksBy = client myApi host
509+-- > where host = BaseUrl Http "localhost" 8080
502510-- > -- then you can just use "getBooksBy" to query that endpoint.
503511-- > -- 'getBooksBy Nothing' for all books
504512-- > -- 'getBooksBy (Just "Isaac Asimov")' to get all books by Isaac Asimov
@@ -536,13 +544,14 @@ instance (KnownSymbol sym, ToText a, HasClient sublayout)
536544--
537545-- Example:
538546--
539−-- > type MyApi = "books" :> MatrixParams "authors" Text :> Get [Book]
547+-- > type MyApi = "books" :> MatrixParams "authors" Text :> Get '[JSON] [Book]
540548-- >
541549-- > myApi :: Proxy MyApi
542550-- > myApi = Proxy
543551-- >
544−-- > getBooksBy :: [Text] -> BaseUrl -> EitherT String IO [Book]
545−-- > getBooksBy = client myApi
552+-- > getBooksBy :: [Text] -> EitherT String IO [Book]
553+-- > getBooksBy = client myApi host
554+-- > where host = BaseUrl Http "localhost" 8080
546555-- > -- then you can just use "getBooksBy" to query that endpoint.
547556-- > -- 'getBooksBy []' for all books
548557-- > -- 'getBooksBy ["Isaac Asimov", "Robert A. Heinlein"]'
@@ -576,13 +585,14 @@ instance (KnownSymbol sym, ToText a, HasClient sublayout)
576585--
577586-- Example:
578587--
579−-- > type MyApi = "books" :> MatrixFlag "published" :> Get [Book]
588+-- > type MyApi = "books" :> MatrixFlag "published" :> Get '[JSON] [Book]
580589-- >
581590-- > myApi :: Proxy MyApi
582591-- > myApi = Proxy
583592-- >
584−-- > getBooks :: Bool -> BaseUrl -> EitherT String IO [Book]
585−-- > getBooks = client myApi
593+-- > getBooks :: Bool -> EitherT String IO [Book]
594+-- > getBooks = client myApi host
595+-- > where host = BaseUrl Http "localhost" 8080
586596-- > -- then you can just use "getBooks" to query that endpoint.
587597-- > -- 'getBooksBy False' for all books
588598-- > -- 'getBooksBy True' to only get _already published_ books
@@ -621,13 +631,14 @@ instance HasClient Raw where
621631--
622632-- Example:
623633--
624−-- > type MyApi = "books" :> ReqBody Book :> Post Book
634+-- > type MyApi = "books" :> ReqBody '[JSON] Book :> Post '[JSON] Book
625635-- >
626636-- > myApi :: Proxy MyApi
627637-- > myApi = Proxy
628638-- >
629−-- > addBook :: Book -> BaseUrl -> EitherT String IO Book
630−-- > addBook = client myApi
639+-- > addBook :: Book -> EitherT String IO Book
640+-- > addBook = client myApi host
641+-- > where host = BaseUrl Http "localhost" 8080
631642-- > -- then you can just use "addBook" to query that endpoint
632643instance (MimeRender ct a, HasClient sublayout)
633644 => HasClient (ReqBody (ct ': cts) a :> sublayout) where
servant-docs/README.md+2−2
@@ -32,7 +32,7 @@ instance ToJSON Greet
3232
3333-- We can also implement 'MimeRender' explicitly for additional formats.
3434instance MimeRender PlainText Greet where
35− toByteString Proxy (Greet s) = "<h1>" <> cs s <> "</h1>"
35+ mimeRender Proxy (Greet s) = "<h1>" <> cs s <> "</h1>"
3636
3737-- we provide a sample value for the 'Greet' type
3838instance ToSample Greet where
@@ -56,7 +56,7 @@ instance ToCapture (Capture "greetid" Text) where
5656type TestApi =
5757 "hello" :> Capture "name" Text :> QueryParam "capital" Bool :> Get '[JSON,PlainText] Greet
5858 :<|> "greet" :> RQBody '[JSON] Greet :> Post '[JSON] Greet
59− :<|> "delete" :> Capture "greetid" Text :> Delete
59+ :<|> "delete" :> Capture "greetid" Text :> Delete '[] ()
6060
6161testApi :: Proxy TestApi
6262testApi = Proxy
servant-docs/src/Servant/Docs.hs+4−3
@@ -30,6 +30,7 @@
3030-- > {-# LANGUAGE OverloadedStrings #-}
3131-- > {-# LANGUAGE TypeOperators #-}
3232-- > {-# OPTIONS_GHC -fno-warn-orphans #-}
33+-- > import Control.Lens
3334-- > import Data.Aeson
3435-- > import Data.Proxy
3536-- > import Data.String.Conversions
@@ -51,7 +52,7 @@
5152-- >
5253-- > -- | We can also implement 'MimeRender' for additional formats like 'PlainText'.
5354-- > instance MimeRender PlainText Greet where
54−-- > toByteString Proxy (Greet s) = "\"" <> cs s <> "\""
55+-- > mimeRender Proxy (Greet s) = "\"" <> cs s <> "\""
5556-- >
5657-- > -- We add some useful annotations to our captures,
5758-- > -- query parameters and request body to make the docs
@@ -111,7 +112,7 @@
111112-- > :<|> "greet" :> ReqBody '[JSON] Greet :> Post '[JSON] Greet
112113-- >
113114-- > -- DELETE /greet/:greetid
114−-- > :<|> "greet" :> Capture "greetid" Text :> Delete
115+-- > :<|> "greet" :> Capture "greetid" Text :> Delete '[JSON] ()
115116-- >
116117-- > testApi :: Proxy TestApi
117118-- > testApi = Proxy
@@ -121,7 +122,7 @@
121122-- > -- notes.
122123-- > extra :: ExtraInfo TestApi
123124-- > extra =
124−-- > extraInfo (Proxy :: Proxy ("greet" :> Capture "greetid" Text :> Delete)) $
125+-- > extraInfo (Proxy :: Proxy ("greet" :> Capture "greetid" Text :> Delete '[JSON] ())) $
125126-- > defAction & headers <>~ ["unicorns"]
126127-- > & notes <>~ [ DocNote "Title" ["This is some text"]
127128-- > , DocNote "Second secton" ["And some more"]