Skip to content

epicallan/hreq

Repository files navigation

Hreq

Hackage MIT license Build status

Intro

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.

Checkout accompanying blog post and minimal tutorial for more details

Motivation

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.

Some of the Key Points

  • 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.

Usage Example

{-# 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)

Attribution

Hreq is heavily inspired by servant-client and ideas from Serv.

Documentation

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 ()

About

A type dependent highlevel HTTP client library inspired by servant-client.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published