@@ -130,12 +130,12 @@ module Network.HTTP.Req
130 -- ** Body
130 -- ** Body
132 , NoReqBody (..)
132 , NoReqBody (..)
133 , ReqBodyBs (..)
135 , ReqBodyBs (..)
134 , ReqBodyLbs (..)
136 , ReqBodyLbs (..)
135 , ReqBodyUrlEnc (..)
137 , ReqBodyUrlEnc (..)
136 , FormUrlEncodedParam
138 , FormUrlEncodedParam
137− , ReqBodyMultipart (..)
139 , HttpBody (..)
139 , HttpBody (..)
140 , ProvidesBody
140 , ProvidesBody
141 -- ** Optional parameters
141 -- ** Optional parameters
@@ -588,6 +588,31 @@ data NoReqBody = NoReqBody
588instance HttpBody NoReqBody where
588instance HttpBody NoReqBody where
589 getRequestBody NoReqBody = L.RequestBodyBS B.empty
589 getRequestBody NoReqBody = L.RequestBodyBS B.empty
591+-- | This body option allows to use a JSON object as request body — probably
592+-- the most popular format right now. Just wrap a data type that is an
593+-- instance of 'ToJSON' type class and you are done: it will be converted to
594+-- JSON and inserted as request body.
596+-- This body option sets the @Content-Type@ header to @\"application/json;
597+-- charset=utf-8\"@ value.
599+newtype ReqBodyJSON a = ReqBodyJSON a
601+instance ToJSON a => HttpBody (ReqBodyJSON a) where
602+ getRequestBody (ReqBodyJSON a) = L.RequestBodyLBS (A.encode a)
603+ getRequestContentType Proxy = pure "application/json; charset=utf-8"
605+-- | This body option streams request body from a file. It is expected that
606+-- the file size does not change during the streaming.
608+-- Using of this body option does not set the @Content-Type@ header.
610+newtype ReqBodyFile = ReqBodyFile FilePath
612+instance HttpBody ReqBodyFile where
613+ getRequestBody (ReqBodyFile path) =
614+ LI.RequestBodyIO (L.streamFile path)
591-- | HTTP request body represented by a strict 'ByteString'.
616-- | HTTP request body represented by a strict 'ByteString'.
593-- Using of this body option does not set the @Content-Type@ header.
618-- Using of this body option does not set the @Content-Type@ header.
@@ -621,7 +646,7 @@ instance HttpBody ReqBodyLbs where
621-- > queryFlag "baz"
646-- > queryFlag "baz"
623-- This body option sets the @Content-Type@ header to
648-- This body option sets the @Content-Type@ header to
624−-- @application/x-www-from-urlencoded@ value.
649+-- @\"application/x-www-from-urlencoded\"@ value.
626newtype ReqBodyUrlEnc = ReqBodyUrlEnc FormUrlEncodedParam
651newtype ReqBodyUrlEnc = ReqBodyUrlEnc FormUrlEncodedParam
@@ -640,21 +665,28 @@ newtype FormUrlEncodedParam = FormUrlEncodedParam [(Text, Maybe Text)]
640instance QueryParam FormUrlEncodedParam where
665instance QueryParam FormUrlEncodedParam where
641 queryParam name mvalue = FormUrlEncodedParam [(name, mvalue)]
666 queryParam name mvalue = FormUrlEncodedParam [(name, mvalue)]
643−-- |
668+-- | A type class for things that can be interpreted as HTTP
645−newtype ReqBodyMultipart = ReqBodyMultipart ByteString
671+class HttpBody body where
647−newtype ReqBodyJSON a = ReqBodyJSON a
673+ {-# MINIMAL getRequestBody #-}
649−instance ToJSON a => HttpBody (ReqBodyJSON a) where
675+ -- | How to get actual 'L.RequestBody'.
650− getRequestBody (ReqBodyJSON a) = L.RequestBodyLBS (A.encode a)
651− getRequestContentType Proxy = pure "application/json; charset=utf-8"
653−class HttpBody body where
654 getRequestBody :: body -> L.RequestBody
677 getRequestBody :: body -> L.RequestBody
679+ -- | This method allows to optionally specify value of @Content-Type@
680+ -- header that should be used when this body option is used. By default
681+ -- this returns 'Nothing' and so @Content-Type@ is not set.
655 getRequestContentType :: Proxy body -> Maybe ByteString
683 getRequestContentType :: Proxy body -> Maybe ByteString
656 getRequestContentType Proxy = Nothing
684 getRequestContentType Proxy = Nothing
686+-- | The type function recognizes 'NoReqBody' as having 'NoBody', while any
687+-- other body option 'CanHaveBody'. This forces user to use 'NoReqBody' with
688+-- 'GET' method and other methods that do not assume any body.
658type family ProvidesBody body :: CanHaveBody where
690type family ProvidesBody body :: CanHaveBody where
659 ProvidesBody NoReqBody = 'NoBody
691 ProvidesBody NoReqBody = 'NoBody
660 ProvidesBody body = 'CanHaveBody
692 ProvidesBody body = 'CanHaveBody