@@ -4,7 +4,7 @@
44{-# LANGUAGE FlexibleContexts #-}
55{-# LANGUAGE FlexibleInstances #-}
66{-# LANGUAGE ScopedTypeVariables #-}
7−module Servant.API.Capture where
7+module Servant.API.Capture (Capture) where
88
99import Data.Proxy
1010import Data.Text
@@ -17,12 +17,34 @@ import Servant.Common.Text
1717import Servant.Docs
1818import Servant.Server
1919
20−-- * Captures
20+-- | Capture a value from the request path under a certain type @a@.
21+--
22+-- Example:
23+--
24+-- > -- GET /books/:isbn
25+-- > type MyApi = "books" :> Capture "isbn" Text :> Get Book
2126data Capture sym a
2227
2328captured :: FromText a => proxy (Capture sym a) -> Text -> Maybe a
2429captured _ = fromText
2530
31+-- | If you use 'Capture' in one of the endpoints for your API,
32+-- this automatically requires your server-side handler to be a function
33+-- that takes an argument of the type specified by the 'Capture'.
34+-- This lets servant worry about getting it from the URL and turning
35+-- it into a value of the type you specify.
36+--
37+-- You can control how it'll be converted from 'Text' to your type
38+-- by simply providing an instance of 'FromText' for your type.
39+--
40+-- Example:
41+--
42+-- > type MyApi = "books" ':>' 'Capture' "isbn" 'Text' ':>' 'Get' Book
43+-- >
44+-- > server :: 'Server' MyApi
45+-- > server = getBook
46+-- > where getBook :: Text -> 'EitherT' (Int, String) IO Book
47+-- > getBook isbn = ...
2648instance (KnownSymbol capture, FromText a, HasServer sublayout)
2749 => HasServer (Capture capture a :> sublayout) where
2850
@@ -40,6 +62,25 @@ instance (KnownSymbol capture, FromText a, HasServer sublayout)
4062
4163 where captureProxy = Proxy :: Proxy (Capture capture a)
4264
65+-- | If you use a 'Capture' in one of your endpoints in your API,
66+-- the corresponding querying function will automatically take
67+-- an additional argument of the type specified by your 'Capture'.
68+-- That function will take care of inserting a textual representation
69+-- of this value at the right place in the request path.
70+--
71+-- You can control how values for this type are turned into
72+-- text by specifying a 'ToText' instance for your type.
73+--
74+-- Example:
75+--
76+-- > type MyApi = "books" ':>' 'Capture' "isbn" 'Text' ':>' 'Get' Book
77+-- >
78+-- > myApi :: Proxy MyApi
79+-- > myApi = Proxy
80+-- >
81+-- > getBook :: Text -> BaseUrl -> EitherT String IO Book
82+-- > getBook = client myApi
83+-- > -- then you can just use "getBook" to query that endpoint
4384instance (KnownSymbol capture, ToText a, HasClient sublayout)
4485 => HasClient (Capture capture a :> sublayout) where
4586
@@ -52,6 +93,8 @@ instance (KnownSymbol capture, ToText a, HasClient sublayout)
5293
5394 where p = unpack (toText val)
5495
96+-- | @"books" :> 'Capture' "isbn" Text@ will appear as
97+-- @/books/:isbn@ in the docs
5598instance (KnownSymbol sym, ToCapture (Capture sym a), HasDocs sublayout)
5699 => HasDocs (Capture sym a :> sublayout) where
57100