request

HTTP client for haskell, inpired by requests and http-dispatch.
Installation
This pacakge is published on hackage with the same name request, you can install it with cabal or stack or nix as any other hackage packages.
Usage
You can try this in haskell REPL once you have request installed:
import Network.HTTP.Request
resp <- get "https://api.leancloud.cn/1.1/date"
print $ responseStatus resp
Record Dot Syntax Support
This library supports modern Haskell record dot syntax. To use it, enable these language extensions:
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedRecordDot #-}
Creating Records with Dot Syntax
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedRecordDot #-}
import Network.HTTP.Request
import qualified Data.ByteString as BS
-- Create request using record dot syntax
let req = Request { method = GET, url = "https://api.leancloud.cn/1.1/date", headers = [], body = Nothing }
-- Response with ByteString body
responseBS <- send req :: IO (Response BS.ByteString)
print responseBS.status -- 200
print responseBS.body -- ByteString response
-- Response with String body
responseStr <- send req :: IO (Response String)
print responseStr.body -- String response
Core API
Request's API has three core concepts: Request record type, Response record type, send function.
Request
Request is all about the information you will send to the target URL.
data Request a = Request
{ method :: Method
, url :: String
, headers :: Headers
, body :: Maybe a
} deriving (Show)
send
Once you have constructed your own Request record, you can call the send function to send it to the server. The send function's type is:
send :: (IsString a) => Request a -> IO (Response a)
Response
Response is what you got from the server URL.
data Response a = Response
{ status :: Int
, headers :: Headers
, body :: a
} deriving (Show)
The response body type a can be any type that implements the IsString constraint, allowing flexible handling of response data.
Backward Compatibility
For users who prefer not to use the language extensions, you can still:
- Create requests using positional arguments:
Request GET "url" [] Nothing
- Use prefixed accessor functions:
requestStatus response, requestHeaders response, etc.
Example
{-# LANGUAGE OverloadedStrings #-}
import Network.HTTP.Request
-- Construct a Request record.
let req = Request GET "https://api.leancloud.cn/1.1/date" [] Nothing
-- Send it.
res <- send req
-- Access the fields on Response.
print $ responseStatus res
Shortcuts
As you expected, there are some shortcuts for the most used scenarios.
get :: String -> IO (Response BS.ByteString)
get url =
send $ Request { method = GET, url = url, headers = [], body = Nothing }
delete :: String -> IO (Response BS.ByteString)
delete url =
send $ Request { method = DELETE, url = url, headers = [], body = Nothing }
post :: (String, Maybe BS.ByteString) -> IO (Response BS.ByteString)
post (url, body) =
send $ Request { method = POST, url = url, headers = [], body = body }
put :: (String, Maybe BS.ByteString) -> IO (Response BS.ByteString)
put (url, body) =
send $ Request { method = PUT, url = url, headers = [], body = body }
These shortcuts' definitions are simple and direct. You are encouraged to add your own if the built-in does not match your use cases, like add custom headers in every request.
API Documents
See the hackage page: http://hackage.haskell.org/package/request/docs/Network-HTTP-Request.html
About the Project
Request is © 2020-2021 by aisk.
License
Request is distributed by a BSD license.