servant-0.2: A family of combinators for defining webservices APIs and serving them

Safe HaskellNone
LanguageHaskell2010

Servant.API.Sub

Synopsis

Documentation

data path :> a infixr 9 Source

The contained API (second argument) can be found under ("/" ++ path) (path being the first argument).

Example:

-- GET /hello/world
-- returning a JSON encoded World value
type MyApi = "hello" :> "world" :> Get World

Constructors

(Proxy path) :> a infixr 9 

Instances

(KnownSymbol s, VLinkHelper * e) => VLinkHelper * ((:>) Symbol s e) 
(KnownSymbol capture, FromText a, HasServer sublayout) => HasServer ((:>) * (Capture Symbol * capture a) sublayout)

If you use Capture 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 Capture. This lets servant worry about getting it from the URL and turning it into a value of the type you specify.

You can control how it'll be converted from Text to your type by simply providing an instance of FromText for your type.

Example:

type MyApi = "books" :> Capture "isbn" Text :> Get Book

server :: Server MyApi
server = getBook
  where getBook :: Text -> EitherT (Int, String) IO Book
        getBook isbn = ...
(KnownSymbol sym, FromText a, HasServer sublayout) => HasServer ((:>) * (Header Symbol * sym a) sublayout)

If you use Header 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 Header. 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 FromText instance.

Example:

newtype Referer = Referer Text
  deriving (Eq, Show, FromText, ToText)

           -- GET /view-my-referer
type MyApi = "view-my-referer" :> Header "Referer" Referer :> Get Referer

server :: Server MyApi
server = viewReferer
  where viewReferer :: Referer -> EitherT (Int, String) IO referer
        viewReferer referer = return referer
(KnownSymbol sym, HasServer sublayout) => HasServer ((:>) * (QueryFlag Symbol sym) sublayout)

If you use QueryFlag "published" 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 Bool.

Example:

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...
(KnownSymbol sym, FromText a, HasServer sublayout) => HasServer ((:>) * (QueryParams Symbol * sym a) sublayout)

If you use QueryParams "authors" Text 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 [Text].

This lets servant worry about looking up 0 or more values in the query string associated to authors and turning each of them into a value of the type you specify.

You can control how the individual values are converted from Text to your type by simply providing an instance of FromText for your type.

Example:

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...
(KnownSymbol sym, FromText a, HasServer sublayout) => HasServer ((:>) * (QueryParam Symbol * sym a) sublayout)

If you use QueryParam "author" Text 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 Maybe Text.

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 Maybe, because it may not be there and servant would then hand you Nothing.

You can control how it'll be converted from Text to your type by simply providing an instance of FromText for your type.

Example:

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...
(FromJSON a, HasServer sublayout) => HasServer ((:>) * (ReqBody * a) sublayout)

If you use ReqBody 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 ReqBody. 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 FromJSON instance.

Example:

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...
(KnownSymbol path, HasServer sublayout) => HasServer ((:>) Symbol path sublayout)

Make sure the incoming request starts with "/path", strip it and pass the rest of the request path to sublayout.

type Server ((:>) * (Capture Symbol * capture a) sublayout) = a -> Server sublayout 
type Server ((:>) * (Header Symbol * sym a) sublayout) = Maybe a -> Server sublayout 
type Server ((:>) * (QueryFlag Symbol sym) sublayout) = Bool -> Server sublayout 
type Server ((:>) * (QueryParams Symbol * sym a) sublayout) = [a] -> Server sublayout 
type Server ((:>) * (QueryParam Symbol * sym a) sublayout) = Maybe a -> Server sublayout 
type Server ((:>) * (ReqBody * a) sublayout) = a -> Server sublayout 
type Server ((:>) Symbol path sublayout) = Server sublayout