The immediate feedback provided by Haskell playgrounds combines nicely with Haskell's powerful support for network programming and JSON parsing. Together they facilitate the interactive programmatic exploration of network APIs.

To see this in action, let's have a look at some queries taken from the tutorial of the web client library wreq. It comes pre-installed with Haskell for Mac and can be imported as Network.Wreq. Together with the powerful lens interface to the fast JSON library aeson, getting data out of a Web API is easy.

We start by issuing a GET request and extracting the response status, and then, just the status code.

Given a data type with a lens interface, such as a HTTP Response, we can use (^.) —aka view— with a getter (or access path) to extract components from that data type, such as reaching into a HTTP response to get the status code. Standard function composition (.) serves to compose elements of the access path, providing us with an OO-style dot syntax.

In contrast to the simple get function wreq's getWith takes a set of options to add request parameters and to specify authentication schemes and similar. In the following, we use it to add two request parameters. Then, we extract the entire response body and print it.

Finally, we use an access path again, to now extract the value of the JSON key url and cast that to a String (with the _String combinator).

The wreq package supports a range of more advanced features including various authentication schemes, cookies, convenient error handling, and sessions. Moreover lens, despite its admittedly somewhat steep learning curve, facilitates compact and clear JSON traversals both to extract values and to construct and rewrite JSON values.

The Code

If you want to try this yourself, you will need the following language pragma and imports:

{-# LANGUAGE OverloadedStrings #-}

import Network.Wreq
import Control.Lens
import Data.Aeson.Lens (_String, key)
import Data.ByteString.Lazy.Char8 as BS

And for your copy and pasting pleasure, here the code from the screenshots:

result <- get ""

let opts = defaults & param "foo" .~ ["bar", "quux"]
result <- getWith opts ""
BS.putStrLn $ result^.responseBody

result^.responseBody.(key "url")._String

Have a look at the wreq tutorial for more details.