Hreq is a high-level easy to use type-driven HTTP client library inspired by Servant-Client. Hreq provides an alternative approach to type-safe construction and interpretation of API endpoints for Http client requests.
The Hreq github repository is a mono-repo composed of the following:
-
hreq-core implementing core functionality.
-
hreq-client an HTTP client using hreq-core functionality
-
hreq-conduit an HTTP client with streaming support via conduit.
Hreq was motivated by the simplicity and ease of use of req and the type driven elegance of servant-client. I envisioned Hreq as the best possible compromise of both worlds.
-
A default HTTP client manager is set up within the library such that one doesn't have to think about manager configuration.
-
Hreq provides type synonyms for common API type combinators, therefore, reducing on API types verbosity.
-
In Hreq, API types are used directly within API functions via Type Application while in servant-client API types create new API functions for creating API requests.
-
In Hreq, API Request component arguments are provided to the API function through a Heterogeneous list.
-
Hreq supports the concept of Retry policy, whereby an http request is retried automatically on network connection failure based on a set Retry policy.
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DataKinds #-}
module Main where
import Data.Aeson (FromJSON, ToJSON)
import GHC.Generics (Generic)
import Hreq.Client
data User = User
{ name :: String
, age :: Int
} deriving (Show, Generic, FromJSON, ToJSON)
main' :: IO ()
main' = do
res <- runHreq baseUrl $ do
-- | Makes Post request with newUser as a request body
createdUser <- createUser newUser
-- | Makes Get Request with "allan" as a URL fragment
myUser <- getUserByName "allan"
-- | Makes a Get Request returning a list of Users
allUsers <- hreq @(GetJson [User]) Empty
return (createdUser, myUser, allUsers)
print res
where
baseUrl :: BaseUrl
baseUrl = HttpDomain "example.com"
newUser :: User
newUser = User "Allan" 29
createUser :: RunClient m => User -> m User
createUser user = hreq @(JsonBody User :> PostJson User) (user :. Empty)
getUserByName :: RunClient m => String -> m User
getUserByName userName = hreq @(Capture String :> GetJson User) (userName :. Empty)
Hreq is heavily inspired by servant-client and ideas from Serv.
This README is tested by markdown-unlit
to make sure the code builds. To keep that happy, we do need a main
in this file, so ignore the following :)
main :: IO ()
main = pure ()