diff --git a/Servant-API-Header.html b/Servant-API-Header.html new file mode 100644 index 00000000..55c7e58c --- /dev/null +++ b/Servant-API-Header.html @@ -0,0 +1,21 @@ +Servant.API.Header

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

Safe HaskellNone
LanguageHaskell2010

Servant.API.Header

Synopsis

Documentation

data Header sym a Source

Extract the given header's value as a value of type a.

Example:

newtype Referer = Referer Text
+  deriving (Eq, Show, FromText, ToText)
+
+           -- GET /view-my-referer
+type MyApi = "view-my-referer" :> Header "from" Referer :> Get Referer

Instances

(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
type Server ((:>) * (Header Symbol * sym a) sublayout) = Maybe a -> Server sublayout 
\ No newline at end of file diff --git a/Servant-API-Sub.html b/Servant-API-Sub.html index 464947fd..98890f20 100644 --- a/Servant-API-Sub.html +++ b/Servant-API-Sub.html @@ -14,7 +14,20 @@ type MyApi = "hello" :> "world" :> Get World(KnownSymbol sym, HasServer sublayout) => HasServer ((:>) * (QueryFlag Symbol sym) sublayout)

If you use QueryFlag "published" in one of the endpoints for your API, + 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]
 
@@ -53,4 +66,4 @@ 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 ((:>) * (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  \ No newline at end of file + 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  \ No newline at end of file diff --git a/Servant-API.html b/Servant-API.html index 68ce77c5..3ea96d3d 100644 --- a/Servant-API.html +++ b/Servant-API.html @@ -1,4 +1,4 @@ Servant.API

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

Safe HaskellNone
LanguageHaskell2010

Servant.API

Contents

Synopsis

Combinators

Type-level combinator for expressing subrouting: :>

Type-level combinator for alternative endpoints: :<|>

Accessing information from the request

Capturing parts of the url path as parsed values: Capture

Retrieving parameters from the query string of the URI: QueryParam

Accessing the request body as a JSON-encoded type: ReqBody

Actual endpoints, distinguished by HTTP method

GET requests

POST requests

DELETE requests

PUT requests

Untyped endpoints

Plugging in a wai Application, serving directories

Utilities

QuasiQuotes for endpoints

module Servant.QQ

Type-safe internal URLs

\ No newline at end of file +

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

Safe HaskellNone
LanguageHaskell2010

Servant.API

Contents

Synopsis

Combinators

Type-level combinator for expressing subrouting: :>

Type-level combinator for alternative endpoints: :<|>

Accessing information from the request

Capturing parts of the url path as parsed values: Capture

Retrieving specific headers from the request

Retrieving parameters from the query string of the URI: QueryParam

Accessing the request body as a JSON-encoded type: ReqBody

Actual endpoints, distinguished by HTTP method

GET requests

POST requests

DELETE requests

PUT requests

Untyped endpoints

Plugging in a wai Application, serving directories

Utilities

QuasiQuotes for endpoints

module Servant.QQ

Type-safe internal URLs

\ No newline at end of file diff --git a/Servant-Server.html b/Servant-Server.html index 8a12442c..249694c7 100644 --- a/Servant-Server.html +++ b/Servant-Server.html @@ -74,7 +74,20 @@ server = listAllBooks :<|> postBook server :: Server MyApi server = getBook where getBook :: Text -> EitherT (Int, String) IO Book - getBook isbn = ...(KnownSymbol sym, HasServer sublayout) => HasServer ((:>) * (QueryFlag Symbol sym) sublayout)

If you use QueryFlag "published" in one of the endpoints for your API, + 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]
 
diff --git a/doc-index.html b/doc-index.html
index 986b4f09..3ea1e0c8 100644
--- a/doc-index.html
+++ b/doc-index.html
@@ -1,4 +1,4 @@
 servant-0.2: A family of combinators for defining webservices APIs and serving them (Index)

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

Index

:<|> 
1 (Type/Class)Servant.API.Alternative, Servant.API, Servant
2 (Data Constructor)Servant.API.Alternative, Servant.API, Servant
:> 
1 (Type/Class)Servant.API.Sub, Servant.API, Servant
2 (Data Constructor)Servant.API.Sub, Servant.API, Servant
>:Servant.QQ, Servant
AndServant.Utils.Links, Servant
blockCommentServant.QQ, Servant
CaptureServant.API.Capture, Servant.API, Servant
captureServant.QQ, Servant
conjServant.QQ, Servant
DeleteServant.API.Delete, Servant.API, Servant
deleteServant.QQ, Servant
eolServant.QQ, Servant
eolsServant.QQ, Servant
ExpSYMServant.QQ, Servant
failWithServant.Server, Servant
FromTextServant.Common.Text, Servant
fromTextServant.Common.Text, Servant
GetServant.API.Get, Servant.API, Servant
getServant.QQ, Servant
HasServerServant.Server, Servant
inlineCommentServant.QQ, Servant
InvalidBodyServant.Server, Servant
IsElemServant.Utils.Links, Servant
IsLinkServant.Utils.Links, Servant
IsLink'Servant.Utils.Links, Servant
IsLink''Servant.Utils.Links, Servant
isMismatchServant.Server, Servant
Link 
1 (Type/Class)Servant.Utils.Links, Servant
2 (Data Constructor)Servant.Utils.Links, Servant
litServant.QQ, Servant
mkLinkServant.Utils.Links, Servant.API, Servant
NotFoundServant.Server, Servant
OrServant.Utils.Links, Servant
parseAllServant.QQ, Servant
parseEntryServant.QQ, Servant
parseMethodServant.QQ, Servant
parseTypServant.QQ, Servant
parseUrlServant.QQ, Servant
parseUrlSegmentServant.QQ, Servant
PostServant.API.Post, Servant.API, Servant
postServant.QQ, Servant
Proxy 
1 (Data Constructor)Servant
2 (Type/Class)Servant
PutServant.API.Put, Servant.API, Servant
putServant.QQ, Servant
QueryFlagServant.API.QueryParam, Servant.API, Servant
QueryParamServant.API.QueryParam, Servant.API, Servant
queryParamServant.QQ, Servant
QueryParamsServant.API.QueryParam, Servant.API, Servant
RawServant.API.Raw, Servant.API, Servant
ReqArgValServant.QQ, Servant
ReqBodyServant.API.ReqBody, Servant.API, Servant
reqBodyServant.QQ, Servant
routeServant.Server, Servant
RouteMismatchServant.Server, Servant
RouteResultServant.Server, Servant
routeResultServant.Server, Servant
RoutingApplicationServant.Server, Servant
RRServant.Server, Servant
serveServant.Server, Servant
serveDirectoryServant.Utils.StaticFiles, Servant.API, Servant
ServerServant.Server, Servant
sitemapServant.QQ, Servant.API, Servant
succeedWithServant.Server, Servant
toApplicationServant.Server, Servant
ToTextServant.Common.Text, Servant
toTextServant.Common.Text, Servant
TypServant.QQ, Servant
ValServant.QQ, Servant
ValidLinkInServant.Utils.Links, Servant
vlhServant.Utils.Links, Servant
VLinkHelperServant.Utils.Links, Servant
WrongMethodServant.Server, Servant
\ No newline at end of file +

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

Index

:<|> 
1 (Type/Class)Servant.API.Alternative, Servant.API, Servant
2 (Data Constructor)Servant.API.Alternative, Servant.API, Servant
:> 
1 (Type/Class)Servant.API.Sub, Servant.API, Servant
2 (Data Constructor)Servant.API.Sub, Servant.API, Servant
>:Servant.QQ, Servant
AndServant.Utils.Links, Servant
blockCommentServant.QQ, Servant
CaptureServant.API.Capture, Servant.API, Servant
captureServant.QQ, Servant
conjServant.QQ, Servant
DeleteServant.API.Delete, Servant.API, Servant
deleteServant.QQ, Servant
eolServant.QQ, Servant
eolsServant.QQ, Servant
ExpSYMServant.QQ, Servant
failWithServant.Server, Servant
FromTextServant.Common.Text, Servant
fromTextServant.Common.Text, Servant
GetServant.API.Get, Servant.API, Servant
getServant.QQ, Servant
HasServerServant.Server, Servant
HeaderServant.API.Header, Servant.API, Servant
inlineCommentServant.QQ, Servant
InvalidBodyServant.Server, Servant
IsElemServant.Utils.Links, Servant
IsLinkServant.Utils.Links, Servant
IsLink'Servant.Utils.Links, Servant
IsLink''Servant.Utils.Links, Servant
isMismatchServant.Server, Servant
Link 
1 (Type/Class)Servant.Utils.Links, Servant
2 (Data Constructor)Servant.Utils.Links, Servant
litServant.QQ, Servant
mkLinkServant.Utils.Links, Servant.API, Servant
NotFoundServant.Server, Servant
OrServant.Utils.Links, Servant
parseAllServant.QQ, Servant
parseEntryServant.QQ, Servant
parseMethodServant.QQ, Servant
parseTypServant.QQ, Servant
parseUrlServant.QQ, Servant
parseUrlSegmentServant.QQ, Servant
PostServant.API.Post, Servant.API, Servant
postServant.QQ, Servant
Proxy 
1 (Data Constructor)Servant
2 (Type/Class)Servant
PutServant.API.Put, Servant.API, Servant
putServant.QQ, Servant
QueryFlagServant.API.QueryParam, Servant.API, Servant
QueryParamServant.API.QueryParam, Servant.API, Servant
queryParamServant.QQ, Servant
QueryParamsServant.API.QueryParam, Servant.API, Servant
RawServant.API.Raw, Servant.API, Servant
ReqArgValServant.QQ, Servant
ReqBodyServant.API.ReqBody, Servant.API, Servant
reqBodyServant.QQ, Servant
routeServant.Server, Servant
RouteMismatchServant.Server, Servant
RouteResultServant.Server, Servant
routeResultServant.Server, Servant
RoutingApplicationServant.Server, Servant
RRServant.Server, Servant
serveServant.Server, Servant
serveDirectoryServant.Utils.StaticFiles, Servant.API, Servant
ServerServant.Server, Servant
sitemapServant.QQ, Servant.API, Servant
succeedWithServant.Server, Servant
toApplicationServant.Server, Servant
ToTextServant.Common.Text, Servant
toTextServant.Common.Text, Servant
TypServant.QQ, Servant
ValServant.QQ, Servant
ValidLinkInServant.Utils.Links, Servant
vlhServant.Utils.Links, Servant
VLinkHelperServant.Utils.Links, Servant
WrongMethodServant.Server, Servant
\ No newline at end of file diff --git a/index-frames.html b/index-frames.html index 6603aca3..95644eb1 100644 --- a/index-frames.html +++ b/index-frames.html @@ -1,4 +1,4 @@ servant-0.2: A family of combinators for defining webservices APIs and serving them

Modules

\ No newline at end of file +

Modules

\ No newline at end of file diff --git a/index.html b/index.html index e6a7a52b..9fa8e44c 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,4 @@ servant-0.2: A family of combinators for defining webservices APIs and serving them

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

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

 
\ No newline at end of file +

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

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

 
\ No newline at end of file diff --git a/mini_Servant-API-Header.html b/mini_Servant-API-Header.html new file mode 100644 index 00000000..3332bd86 --- /dev/null +++ b/mini_Servant-API-Header.html @@ -0,0 +1,4 @@ +Servant.API.Header

Servant.API.Header

data Header sym a

\ No newline at end of file diff --git a/servant.haddock b/servant.haddock index c0557469..596e6196 100644 Binary files a/servant.haddock and b/servant.haddock differ diff --git a/servant.txt b/servant.txt index 8ed014f5..f99f7bfb 100644 --- a/servant.txt +++ b/servant.txt @@ -178,6 +178,45 @@ module Servant.API.Capture data Capture sym a instance (KnownSymbol capture, FromText a, HasServer sublayout) => HasServer (Capture capture a :> sublayout) +module Servant.API.Header + +-- | Extract the given header's value as a value of type a. +-- +-- Example: +-- +--
+--   newtype Referer = Referer Text
+--     deriving (Eq, Show, FromText, ToText)
+--   
+--              -- GET /view-my-referer
+--   type MyApi = "view-my-referer" :> Header "from" Referer :> Get Referer
+--   
+data Header sym a + +-- | 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
+--   
+instance (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (Header sym a :> sublayout) + module Servant.API.QueryParam -- | Lookup the value associated to the sym query string parameter diff --git a/src/Servant-API-Header.html b/src/Servant-API-Header.html new file mode 100644 index 00000000..f8e1634c --- /dev/null +++ b/src/Servant-API-Header.html @@ -0,0 +1,69 @@ + + + + + +src/Servant/API/Header.hs + + + +
{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+module Servant.API.Header where
+
+import Data.Proxy
+import Data.String
+import Data.Text.Encoding (decodeUtf8)
+import GHC.TypeLits
+import Network.Wai
+import Servant.API.Sub
+import Servant.Common.Text
+import Servant.Server
+
+-- | Extract the given header's value as a value of type @a@.
+--
+-- Example:
+--
+-- > newtype Referer = Referer Text
+-- >   deriving (Eq, Show, FromText, ToText)
+-- >
+-- >            -- GET /view-my-referer
+-- > type MyApi = "view-my-referer" :> Header "from" Referer :> Get Referer
+data Header sym a
+
+-- | 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
+instance (KnownSymbol sym, FromText a, HasServer sublayout)
+      => HasServer (Header sym a :> sublayout) where
+
+  type Server (Header sym a :> sublayout) =
+    Maybe a -> Server sublayout
+
+  route Proxy subserver request respond = do
+    let mheader = fromText . decodeUtf8 =<< lookup str (requestHeaders request)
+    route (Proxy :: Proxy sublayout) (subserver mheader) request respond
+
+      where str = fromString $ symbolVal (Proxy :: Proxy sym)
+
+ diff --git a/src/Servant-API.html b/src/Servant-API.html index 657dffc0..d6bf2b66 100644 --- a/src/Servant-API.html +++ b/src/Servant-API.html @@ -18,45 +18,48 @@ -- * Accessing information from the request -- | Capturing parts of the url path as parsed values: @'Capture'@ module Servant.API.Capture, - -- | Retrieving parameters from the query string of the 'URI': @'QueryParam'@ - module Servant.API.QueryParam, - -- | Accessing the request body as a JSON-encoded type: @'ReqBody'@ - module Servant.API.ReqBody, - - -- * Actual endpoints, distinguished by HTTP method - -- | GET requests - module Servant.API.Get, - -- | POST requests - module Servant.API.Post, - -- | DELETE requests - module Servant.API.Delete, - -- | PUT requests - module Servant.API.Put, - - -- * Untyped endpoints - -- | Plugging in a wai 'Network.Wai.Application', serving directories - module Servant.API.Raw, - module Servant.Utils.StaticFiles, - - -- * Utilities - -- | QuasiQuotes for endpoints - module Servant.QQ, - -- | Type-safe internal URLs - module Servant.Utils.Links, - ) where - -import Servant.API.Alternative -import Servant.API.Capture -import Servant.API.Delete -import Servant.API.Get -import Servant.API.Post -import Servant.API.Put -import Servant.API.QueryParam -import Servant.API.Raw -import Servant.API.ReqBody -import Servant.API.Sub -import Servant.QQ (sitemap) -import Servant.Utils.Links (mkLink) -import Servant.Utils.StaticFiles + -- | Retrieving specific headers from the request + module Servant.API.Header, + -- | Retrieving parameters from the query string of the 'URI': @'QueryParam'@ + module Servant.API.QueryParam, + -- | Accessing the request body as a JSON-encoded type: @'ReqBody'@ + module Servant.API.ReqBody, + + -- * Actual endpoints, distinguished by HTTP method + -- | GET requests + module Servant.API.Get, + -- | POST requests + module Servant.API.Post, + -- | DELETE requests + module Servant.API.Delete, + -- | PUT requests + module Servant.API.Put, + + -- * Untyped endpoints + -- | Plugging in a wai 'Network.Wai.Application', serving directories + module Servant.API.Raw, + module Servant.Utils.StaticFiles, + + -- * Utilities + -- | QuasiQuotes for endpoints + module Servant.QQ, + -- | Type-safe internal URLs + module Servant.Utils.Links, + ) where + +import Servant.API.Alternative +import Servant.API.Capture +import Servant.API.Delete +import Servant.API.Get +import Servant.API.Header +import Servant.API.Post +import Servant.API.Put +import Servant.API.QueryParam +import Servant.API.Raw +import Servant.API.ReqBody +import Servant.API.Sub +import Servant.QQ (sitemap) +import Servant.Utils.Links (mkLink) +import Servant.Utils.StaticFiles