1{-# LANGUAGE PolyKinds #-}
2{-# LANGUAGE TypeFamilies #-}
3{-# LANGUAGE TypeOperators #-}
4{-# LANGUAGE FlexibleContexts #-}
5{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE ScopedTypeVariables #-}
7module Servant.API.Capture (Capture) where
15import Servant.Common.Req
16import Servant.Common.Text
20-- | Capture a value from the request path under a certain type @a@.
24-- > -- GET /books/:isbn
25-- > type MyApi = "books" :> Capture "isbn" Text :> Get Book
28captured :: FromText a => proxy (Capture sym a) -> Text -> Maybe a
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.
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.
42-- > type MyApi = "books" ':>' 'Capture' "isbn" 'Text' ':>' 'Get' Book
44-- > server :: 'Server' MyApi
46-- > where getBook :: Text -> 'EitherT' (Int, String) IO Book
47-- > getBook isbn = ...
48instance (KnownSymbol capture, FromText a, HasServer sublayout)
49 => HasServer (Capture capture a :> sublayout) where
51 type Server (Capture capture a :> sublayout) =
54 route Proxy subserver request respond = case pathInfo request of
56 -> case captured captureProxy first of
57 Nothing -> respond $ failWith NotFound
58 Just v -> route (Proxy :: Proxy sublayout) (subserver v) request{
61 _ -> respond $ failWith NotFound
63 where captureProxy = Proxy :: Proxy (Capture capture a)
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.
71-- You can control how values for this type are turned into
72-- text by specifying a 'ToText' instance for your type.
76-- > type MyApi = "books" ':>' 'Capture' "isbn" 'Text' ':>' 'Get' Book
78-- > myApi :: Proxy MyApi
81-- > getBook :: Text -> BaseUrl -> EitherT String IO Book
82-- > getBook = client myApi
83-- > -- then you can just use "getBook" to query that endpoint
84instance (KnownSymbol capture, ToText a, HasClient sublayout)
85 => HasClient (Capture capture a :> sublayout) where
87 type Client (Capture capture a :> sublayout) =
90 clientWithRoute Proxy req val =
91 clientWithRoute (Proxy :: Proxy sublayout) $
94 where p = unpack (toText val)
96-- | @"books" :> 'Capture' "isbn" Text@ will appear as
97-- @/books/:isbn@ in the docs
98instance (KnownSymbol sym, ToCapture (Capture sym a), HasDocs sublayout)
99 => HasDocs (Capture sym a :> sublayout) where
101 docsFor Proxy (endpoint, action) =
102 docsFor sublayoutP (endpoint', action')
104 where sublayoutP = Proxy :: Proxy sublayout
105 captureP = Proxy :: Proxy (Capture sym a)
107 action' = over captures (|> toCapture captureP) action
108 endpoint' = over path (\p -> p++"/:"++symbolVal symP) endpoint
109 symP = Proxy :: Proxy sym
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list