@@ -32,22 +32,24 @@
3232-- when you do, it's better import it qualified because it has naming
3333-- conflicts with @req@.
3434
35−{-# LANGUAGE DataKinds #-}
36−{-# LANGUAGE DeriveDataTypeable #-}
37−{-# LANGUAGE DeriveGeneric #-}
38−{-# LANGUAGE FlexibleInstances #-}
39−{-# LANGUAGE GADTs #-}
40−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
41−{-# LANGUAGE KindSignatures #-}
42−{-# LANGUAGE MultiParamTypeClasses #-}
43−{-# LANGUAGE OverloadedStrings #-}
44−{-# LANGUAGE RecordWildCards #-}
45−{-# LANGUAGE ScopedTypeVariables #-}
46−{-# LANGUAGE TypeFamilies #-}
47−{-# LANGUAGE UndecidableInstances #-}
35+{-# LANGUAGE DataKinds #-}
36+{-# LANGUAGE DeriveDataTypeable #-}
37+{-# LANGUAGE DeriveGeneric #-}
38+{-# LANGUAGE FlexibleInstances #-}
39+{-# LANGUAGE GADTs #-}
40+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
41+{-# LANGUAGE KindSignatures #-}
42+{-# LANGUAGE MultiParamTypeClasses #-}
43+{-# LANGUAGE OverloadedStrings #-}
44+{-# LANGUAGE RecordWildCards #-}
45+{-# LANGUAGE ScopedTypeVariables #-}
46+{-# LANGUAGE TypeFamilies #-}
47+{-# LANGUAGE UndecidableInstances #-}
48+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
4849
4950module Network.HTTP.Req
5051 ( -- * Making a request
52+ -- $making-a-request
5153 req
5254 -- * Embedding requests into your monad
5355 -- $embedding-requests
@@ -91,9 +93,8 @@ module Network.HTTP.Req
9193 , CanHaveBody (..) )
9294where
9395
94−import Control.Monad.Error (MonadError (..))
96+import Control.Exception (try)
9597import Control.Monad.IO.Class
96−import Control.Monad.Reader
9798import Data.Aeson
9899import Data.ByteString
99100import Data.Data (Data)
@@ -117,24 +118,37 @@ import qualified Network.HTTP.Types as Y
117118----------------------------------------------------------------------------
118119-- Making a request
119120
120−-- | Perform an HTTP request.
121+-- $making-a-request
122+--
123+-- To make an HTTP request you need only one function: 'req'.
124+
125+-- | Make an HTTP request.
126+--
127+-- TODO Finish docs of this function when the package is more developed.
121128
122129req
123− :: ( MonadHttp m
130+ :: forall m method body response.
131+ ( MonadHttp m
124132 , HttpMethod method
125133 , HttpBody body
126134 , HttpResponse response
127135 , AllowsBody method ~ ProvidesBody body )
128− => method
129− -> Endpoint
130− -> body
131− -> Option
132− -> m response
133−req = undefined
134−
135−-- TODO We need to catch exceptions here, only relevant ones and only
136−-- synchronous to give user a chance to work with pure, explicit exceptions
137−-- if he wants to do so.
136+ => method -- ^ HTTP method
137+ -> Endpoint -- ^ Endpoint to make the request against
138+ -> body -- ^ Body of the request
139+ -> Option -- ^ Collection of optional parameters
140+ -> m response -- ^ Response
141+req method url body options = do
142+ config <- getHttpConfig
143+ manager <- liftIO (readIORef globalManager)
144+ let request = flip appEndo L.defaultRequest $
145+ getRequestMod (Womb method :: Womb "method" method) <>
146+ getRequestMod url <>
147+ getRequestMod (Womb body :: Womb "body" body) <>
148+ getRequestMod options <>
149+ getRequestMod config
150+ liftIO (try $ getHttpResponse manager request)
151+ >>= either handleHttpException return
138152
139153----------------------------------------------------------------------------
140154-- Embedding requests into your monad
@@ -448,7 +462,9 @@ port = undefined -- TODO
448462-- Here we need to provide various options how to consume responses.
449463
450464class HttpResponse response where
451− interpretResponse :: ByteString -> response -- FIXME use conduit
465+ getHttpResponse :: L.Manager -> L.Request -> IO response
466+
467+-- helpers to
452468
453469----------------------------------------------------------------------------
454470-- Other