req is:exact

HTTP client library HTTP client library.
Make an HTTP request. The function takes 5 arguments, 4 of which specify required parameters and the final Option argument is a collection of optional parameters. Let's go through all the arguments first: req method url body response options. method is an HTTP method such as GET or POST. The documentation has a dedicated section about HTTP methods below. url is a Url that describes location of resource you want to interact with. body is a body option such as NoReqBody or ReqBodyJson. The tutorial has a section about HTTP bodies, but usage is very straightforward and should be clear from the examples. response is a type hint how to make and interpret response of an HTTP request. Out-of-the-box it can be the following: Finally, options is a Monoid that holds a composite Option for all other optional settings like query parameters, headers, non-standard port number, etc. There are quite a few things you can put there, see the corresponding section in the documentation. If you don't need anything at all, pass mempty. Note that if you use req to do all your requests, connection sharing and reuse is done for you automatically. See the examples below to get on the speed quickly.

Examples

First, this is a piece of boilerplate that should be in place before you try the examples:
{-# LANGUAGE DeriveGeneric     #-}
{-# LANGUAGE OverloadedStrings #-}

module Main (main) where

import Control.Monad
import Control.Monad.IO.Class
import Data.Aeson
import Data.Maybe (fromJust)
import Data.Monoid ((<>))
import Data.Text (Text)
import GHC.Generics
import Network.HTTP.Req
import qualified Data.ByteString.Char8 as B
import qualified Text.URI as URI
We will be making requests against the https://httpbin.org service. Make a GET request, grab 5 random bytes:
main :: IO ()
main = runReq defaultHttpConfig $ do
let n :: Int
n = 5
bs <- req GET (https "httpbin.org" /: "bytes" /~ n) NoReqBody bsResponse mempty
liftIO $ B.putStrLn (responseBody bs)
The same, but now we use a query parameter named "seed" to control seed of the generator:
main :: IO ()
main = runReq defaultHttpConfig $ do
let n, seed :: Int
n    = 5
seed = 100
bs <- req GET (https "httpbin.org" /: "bytes" /~ n) NoReqBody bsResponse $
"seed" =: seed
liftIO $ B.putStrLn (responseBody bs)
POST JSON data and get some info about the POST request:
data MyData = MyData
{ size  :: Int
, color :: Text
} deriving (Show, Generic)

instance ToJSON MyData
instance FromJSON MyData

main :: IO ()
main = runReq defaultHttpConfig $ do
let myData = MyData
{ size  = 6
, color = "Green" }
v <- req POST (https "httpbin.org" /: "post") (ReqBodyJson myData) jsonResponse mempty
liftIO $ print (responseBody v :: Value)
Sending URL-encoded body:
main :: IO ()
main = runReq defaultHttpConfig $ do
let params =
"foo" =: ("bar" :: Text) <>
queryFlag "baz"
response <- req POST (https "httpbin.org" /: "post") (ReqBodyUrlEnc params) jsonResponse mempty
liftIO $ print (responseBody response :: Value)
Using various optional parameters and URL that is not known in advance:
main :: IO ()
main = runReq defaultHttpConfig $ do
-- This is an example of what to do when URL is given dynamically. Of
-- course in a real application you may not want to use 'fromJust'.
uri <- URI.mkURI "https://httpbin.org/get?foo=bar"
let (url, options) = fromJust (useHttpsURI uri)
response <- req GET url NoReqBody jsonResponse $
"from" =: (15 :: Int)           <>
"to"   =: (67 :: Int)           <>
basicAuth "username" "password" <>
options                         <> -- contains the ?foo=bar part
port 443 -- here you can put any port of course
liftIO $ print (responseBody response :: Value)
Extract required value from the given key.