@@ -15,33 +15,34 @@
15-- What does the “easy-to-use” phrase mean? It means that the library is
15-- What does the “easy-to-use” phrase mean? It means that the library is
16-- designed to be beginner-friendly, so it's simple to add it to your monad
16-- designed to be beginner-friendly, so it's simple to add it to your monad
17-- stack, intuitive to work with, well-documented, and does not get in your
17-- stack, intuitive to work with, well-documented, and does not get in your
18+-- way. Doing HTTP requests is a common task and Haskell library for this
19+-- should be very approachable and clear to beginners. On this path certain
18−-- way. On this path certain compromises were made. For example one cannot
20+-- compromises were made. For example one cannot currently modify
19−-- currently modify 'L.ManagerSettings' of default manager because the
21+-- 'L.ManagerSettings' of default manager because the library always use the
20−-- library always use the same implicit global manager for simplicity and
22+-- same implicit global manager for simplicity and maximal connection
21−-- maximal connection sharing. There is a way to use your own manager with
23+-- sharing. There is a way to use your own manager with different settings,
22−-- different settings, but it requires a bit more typing. Doing HTTP
24+-- but it requires a bit more typing.
23−-- requests is a common task and Haskell library for this should be very
24−-- approachable and clear to beginners.
26-- “Type-safe” means that the library is protective and eliminates certain
26-- “Type-safe” means that the library is protective and eliminates certain
27-- class of errors compared to alternative libraries like @wreq@ or vanilla
27-- class of errors compared to alternative libraries like @wreq@ or vanilla
28−-- @http-client@. For example we have correct-by-construction 'Url's, it's
28+-- @http-client@. For example, we have correct-by-construction 'Url's, it's
29-- guaranteed that user does not send request body when using methods like
29-- guaranteed that user does not send request body when using methods like
30−-- 'GET' or 'DELETE', amount of implicit assumptions is minimized by making
30+-- 'GET' or 'OPTIONS', amount of implicit assumptions is minimized by making
31-- user specify his\/her intentions in explicit form (for example it's not
31-- user specify his\/her intentions in explicit form (for example it's not
32−-- possible to avoid specifying body or method of a request). The library
32+-- possible to avoid specifying body or method of a request). Authentication
33+-- methods that assume TLS will force user to use TLS on type level. The
33−-- carefully hides underlying types from lower-level @http-client@ package
34+-- library carefully hides underlying types from lower-level @http-client@
34−-- because it's not type safe enough (for example 'L.Request' is an instance
35+-- package because it's not type safe enough (for example 'L.Request' is an
35−-- of 'Data.String.IsString' and if it's malformed, it will blow up at
36+-- instance of 'Data.String.IsString' and if it's malformed, it will blow up
36−-- run-time).
37+-- at run-time).
38-- “Expandable” refers to the ability of the library to be expanded without
39-- “Expandable” refers to the ability of the library to be expanded without
39-- ugly hacking. For example it's possible to define your own HTTP methods,
40-- ugly hacking. For example it's possible to define your own HTTP methods,
40-- new ways to construct body of request, new authorization options, new
41-- new ways to construct body of request, new authorization options, new
41−-- ways to actually perform request and how to represent\/parse its
42+-- ways to actually perform request and how to represent\/parse response. As
42−-- response. As user extends the library to satisfy his\/her special needs,
43+-- user extends the library to satisfy his\/her special needs, the new
43−-- the new solutions work just like built-ins. That said, all common cases
44+-- solutions work just like built-ins. That said, all common cases are
44−-- are covered by the library out-of-the-box.
45+-- covered by the library out-of-the-box.
46-- “High-level” means that there are less details to worry about. The
47-- “High-level” means that there are less details to worry about. The
47-- library is a result of my experiences as a Haskell consultant, working
48-- library is a result of my experiences as a Haskell consultant, working
@@ -51,7 +52,7 @@
51-- concerned with purity: just define 'handleHttpException' accordingly when
52-- concerned with purity: just define 'handleHttpException' accordingly when
52-- making your monad instance of 'MonadHttp' and it will play seamlessly.
53-- making your monad instance of 'MonadHttp' and it will play seamlessly.
53-- Finally, the library cuts boilerplate considerably and helps write
54-- Finally, the library cuts boilerplate considerably and helps write
54−-- concise, easy to read code, thanks to its minimal and uniform API.
55+-- concise, easy to read and maintain code.
56-- The documentation below is structured in such a way that most important
57-- The documentation below is structured in such a way that most important
57-- information goes first: you learn how to do HTTP requests, then how to
58-- information goes first: you learn how to do HTTP requests, then how to
@@ -68,12 +69,15 @@
68-- client used everywhere in Haskell.
69-- client used everywhere in Haskell.
69-- * <https://hackage.haskell.org/package/http-client-tls> — TLS (HTTPS)
70-- * <https://hackage.haskell.org/package/http-client-tls> — TLS (HTTPS)
70-- support for @http-client@.
71-- support for @http-client@.
71−-- * <https://hackage.haskell.org/package/http-conduit> — conduit
72−-- interface to @http-client@.
74-- You won't need low-level interface of @http-client@ most of the time, but
73-- You won't need low-level interface of @http-client@ most of the time, but
75-- when you do, it's better import it qualified because it has naming
74-- when you do, it's better import it qualified because it has naming
76-- conflicts with @req@.
75-- conflicts with @req@.
77+-- Finally, it's important to note that since we leverage other well-known
78+-- libraries that the whole Haskell ecosystem uses, there is no risk in
79+-- using @req@, as the machinery for performing requests is the same as with
80+-- @http-conduit@ and @wreq@, it's just the API is different.
78{-# LANGUAGE DataKinds #-}
82{-# LANGUAGE DataKinds #-}
79{-# LANGUAGE DeriveDataTypeable #-}
83{-# LANGUAGE DeriveDataTypeable #-}
@@ -96,7 +100,7 @@ module Network.HTTP.Req
96 , HttpConfig (..)
100 , HttpConfig (..)
97 -- * Request
101 -- * Request
98 -- ** Methods
102 -- ** Methods
99− -- $request-methods
103+ -- $methods
100 , GET (..)
104 , GET (..)
101 , POST (..)
105 , POST (..)
102 , HEAD (..)
106 , HEAD (..)
@@ -108,6 +112,7 @@ module Network.HTTP.Req
108 , PATCH (..)
112 , PATCH (..)
109 , HttpMethod (..)
113 , HttpMethod (..)
110 -- ** URL
114 -- ** URL
@@ -117,17 +122,19 @@ module Network.HTTP.Req
117 -- ** Body
122 -- ** Body
118 , HttpBody (..) -- TODO more stuff here
123 , HttpBody (..) -- TODO more stuff here
119 -- ** Optional parameters
124 -- ** Optional parameters
120− -- $request-optional-parameters
125+ -- $optional-parameters
122 -- *** Query parameters
127 -- *** Query parameters
128+ -- $query-parameters
124 , queryFlag
130 , queryFlag
125 , QueryParam (..)
131 , QueryParam (..)
126 -- *** Headers
132 -- *** Headers
128 -- *** Cookies
134 -- *** Cookies
129 -- *** Authentication
136 -- *** Authentication
130− -- $request-optional-parameters-authentication
137+ -- $authentication
131 , basicAuth
138 , basicAuth
133 , oAuth2Bearer
140 , oAuth2Bearer
@@ -139,8 +146,10 @@ module Network.HTTP.Req
139 , responseTimeout
146 , responseTimeout
140 , httpVersion
147 , httpVersion
141 -- * Response
148 -- * Response
142 , HttpResponse (..)
150 , HttpResponse (..)
143 -- * Other
151 -- * Other
144 , CanHaveBody (..)
153 , CanHaveBody (..)
145 , Scheme (..) )
154 , Scheme (..) )
@@ -275,14 +284,14 @@ class MonadIO m => MonadHttp m where
275-- making HTTP requests.
284-- making HTTP requests.
277data HttpConfig = HttpConfig
286data HttpConfig = HttpConfig
278− { httpConfigProxy :: !(Maybe L.Proxy)
287+ { httpConfigProxy :: Maybe L.Proxy
279 -- ^ Proxy to use. By default values of @HTTP_PROXY@ and @HTTPS_PROXY@
288 -- ^ Proxy to use. By default values of @HTTP_PROXY@ and @HTTPS_PROXY@
280 -- environment variables are respected, this setting overwrites them.
289 -- environment variables are respected, this setting overwrites them.
281 -- Default value: 'Nothing'.
290 -- Default value: 'Nothing'.
282− , httpConfigRedirectCount :: !Word
291+ , httpConfigRedirectCount :: Word
283 -- ^ How many redirects to follow when getting a resource. Default
292 -- ^ How many redirects to follow when getting a resource. Default
284 -- value: 10.
293 -- value: 10.
285− , httpConfigAltManager :: !(Maybe L.Manager)
294+ , httpConfigAltManager :: Maybe L.Manager
286 -- ^ Alternative 'L.Manager' to use. 'Nothing' (default value) means
295 -- ^ Alternative 'L.Manager' to use. 'Nothing' (default value) means
287 -- that default implicit manager will be used (that's what you want in
296 -- that default implicit manager will be used (that's what you want in
288 -- 99% of cases).
297 -- 99% of cases).
@@ -305,7 +314,7 @@ instance Default HttpConfig where
305 let Y.Status statusCode _ = L.responseStatus response in
314 let Y.Status statusCode _ = L.responseStatus response in
306 unless (200 <= statusCode && statusCode < 300) $ do
315 unless (200 <= statusCode && statusCode < 300) $ do
307 chunk <- BL.toStrict <$> L.brReadSome (L.responseBody response) 1024
316 chunk <- BL.toStrict <$> L.brReadSome (L.responseBody response) 1024
308− LI.throwHttp (L.StatusCodeException (() <$ response) chunk) }
317+ LI.throwHttp (L.StatusCodeException (void response) chunk) }
310instance RequestComponent HttpConfig where
319instance RequestComponent HttpConfig where
311 getRequestMod HttpConfig {..} = Endo $ \x ->
320 getRequestMod HttpConfig {..} = Endo $ \x ->
@@ -317,9 +326,9 @@ instance RequestComponent HttpConfig where
317----------------------------------------------------------------------------
326----------------------------------------------------------------------------
318-- Request — Methods
327-- Request — Methods
320−-- $request-methods
329+-- $methods
322−-- The package provides all methods as defined by RFC 2616, and 'PATCH'
331+-- The package supports all methods as defined by RFC 2616, and 'PATCH'
323-- which is defined by RFC 5789 — that should be enough to talk to RESTful
332-- which is defined by RFC 5789 — that should be enough to talk to RESTful
324-- APIs. In some cases however, you may want to add more methods (e.g. you
333-- APIs. In some cases however, you may want to add more methods (e.g. you
325-- work with WebDAV <https://en.wikipedia.org/wiki/WebDAV>); no need to
334-- work with WebDAV <https://en.wikipedia.org/wiki/WebDAV>); no need to
@@ -358,7 +367,10 @@ instance HttpMethod PUT where
358 type AllowsBody PUT = 'CanHaveBody
367 type AllowsBody PUT = 'CanHaveBody
359 httpMethodName Proxy = Y.methodPut
368 httpMethodName Proxy = Y.methodPut
361−-- | 'DELETE' method.
370+-- | 'DELETE' method. This data type does not allow having request body with
371+-- 'DELETE' requests, as it should be, however some APIs may expect 'DELETE'
372+-- requests to have bodies, in that case define your own variation of
373+-- 'DELETE' method and allow it having a body.
363data DELETE = DELETE
375data DELETE = DELETE
@@ -427,9 +439,14 @@ instance HttpMethod method => RequestComponent (Womb "method" method) where
427----------------------------------------------------------------------------
439----------------------------------------------------------------------------
428-- Request — URL
440-- Request — URL
444+-- We use 'Url's which are correct by construction, see 'Url'. To build a
445+-- 'Url' from 'ByteString', use 'parseUrlHttp' or 'parseUrlHttps'.
430-- | Request's 'Url'. Start constructing your 'Url' with 'http' or 'https'
447-- | Request's 'Url'. Start constructing your 'Url' with 'http' or 'https'
431-- specifying the scheme and host at the same time. Then use the @('/:')@
448-- specifying the scheme and host at the same time. Then use the @('/:')@
432−-- constructor to grow path one piece at a time. Every single piece of path
449+-- operator to grow path one piece at a time. Every single piece of path
433-- will be url(percent)-encoded, so @('/:')@ is the only way to have forward
450-- will be url(percent)-encoded, so @('/:')@ is the only way to have forward
434-- slashes between path segments. This approach makes working with dynamic
451-- slashes between path segments. This approach makes working with dynamic
435-- path segments easy and safe. See examples below how to represent various
452-- path segments easy and safe. See examples below how to represent various
@@ -540,7 +557,7 @@ instance HttpBody b => RequestComponent (Womb "body" b) where
540----------------------------------------------------------------------------
557----------------------------------------------------------------------------
541-- Request — Optional parameters
558-- Request — Optional parameters
543−-- $request-optional-parameters
560+-- $optional-parameters
545-- Optional parameters to a request include things like query parameters,
562-- Optional parameters to a request include things like query parameters,
546-- headers, port number, etc. All optional parameters have the type
563-- headers, port number, etc. All optional parameters have the type
@@ -597,6 +614,10 @@ instance RequestComponent (Option scheme) where
597----------------------------------------------------------------------------
614----------------------------------------------------------------------------
598-- Request — Optional parameters — Query Parameters
615-- Request — Optional parameters — Query Parameters
600-- | This operator builds a query parameter that will be included in URL of
621-- | This operator builds a query parameter that will be included in URL of
601-- your request after question sign @?@. This is the same syntax you use
622-- your request after question sign @?@. This is the same syntax you use
602-- with form URL encoded request bodies.
623-- with form URL encoded request bodies.
@@ -659,12 +680,12 @@ attachHeader name value x =
659----------------------------------------------------------------------------
680----------------------------------------------------------------------------
660-- Request — Optional parameters — Cookies
681-- Request — Optional parameters — Cookies
662−-- TODO No idea right now.
683+-- $cookies
664----------------------------------------------------------------------------
685----------------------------------------------------------------------------
665-- Request — Optional parameters — Authentication
686-- Request — Optional parameters — Authentication
667−-- $request-optional-parameters-authentication
688+-- $authentication
669-- TODO Something. You should always prefer authentication 'Option's to
690-- TODO Something. You should always prefer authentication 'Option's to
670-- manual construction of headers, etc., because it's a better style and
691-- manual construction of headers, etc., because it's a better style and
@@ -782,6 +803,10 @@ httpVersion major minor = withRequest $ \x ->
782----------------------------------------------------------------------------
803----------------------------------------------------------------------------
783-- Response
804-- Response
785-- Here we need to provide various options how to consume responses.
810-- Here we need to provide various options how to consume responses.
787class HttpResponse response where
812class HttpResponse response where
@@ -792,6 +817,10 @@ class HttpResponse response where
792----------------------------------------------------------------------------
817----------------------------------------------------------------------------
822+-- Just some auxiliary definitions.
795-- | The main class for things that are “parts” of 'L.Request' in the sense
824-- | The main class for things that are “parts” of 'L.Request' in the sense
796-- that if we have a 'L.Request', then we know how to apply an instance of
825-- that if we have a 'L.Request', then we know how to apply an instance of
797-- 'RequestComponent' changing\/overwriting something in it. 'Endo' is
826-- 'RequestComponent' changing\/overwriting something in it. 'Endo' is