free-http-0.1.0.1: README.md
Free Your Client... and Your Requests Will Follow
=================================================
`free-http` is an http-client based on Free Monads. `free-http` exposes a Free Monad to express standard http verbs as well as several backends to interpet programs written in the free monad using various http clients (currently: a pure client, an `http-client`-backed client, and a random client).
See [here](https://github.com/aaronlevin/free-http/blob/master/src/Network/HTTP/Client/Free/Examples.hs#L152) for an example.
To use free-http, simply:
1. Import Network.HTTP.Client.Free to use the library.
2. Choose your base request type by defining your own instance of the `RequestType` type family or importing one from an interpreter. E.g.
```
data MyClient
type instance RequestType MyClient = Request
```
or
```
import Network.HTTP.Free.Client.HttpClient (HttpClient)
```
3. Choose your base response type by defining your own instance of the `ResponseTYpe` type family or importing one from an interpreter. E.g.
```
type instance ResponseType MyClient = Response ByteString
```
or
```
import Network.HTTP.Free.Client.HttpClient (HttpClient)
```
4. Write a program in the 'FreeHttp MyClient m a' free monad.
5. Import an interpreter, such as 'HttpClient'
```
import Network.HTTP.Free.Client.HttpClient
```
6. Run your program against the interpreter:
```
runHttp (myProgram :: FreeHttp MyClient IO String)
```
## Design Choices
### `RequestType` and `ResponseType`
Haskell is fortunate to have several very well-designed http clients: [http-client](https://hackage.haskell.org/package/http-client-0.4.16/docs/Network-HTTP-Client.html), [wreq](http://www.serpentine.com/wreq/), [http-conduit](https://hackage.haskell.org/package/http-conduit), [pipes-http](https://hackage.haskell.org/package/pipes-http), etc. Unfortunately, a few of those clients support several different *Request* and *Response* types. To keep `free-http` flexible, we use two type families defined as:
```
type family RequestType client :: *
type family ResponseType client :: *
```
Our `HttpF` functor is thus defined as:
```
data HttpF client a = HttpF StdMethod (RequestType client) (ResponseType client -> a)
deriving Functor
```
This allows our `HttpF` functor to be agnostic of the foundational request and response type, while allowing interpreter authors to specify the concrete types they need for their http client libraries (e.g. `Request` in the case of `http-client`). A consequence of this is that `free-http` clients (you) need to specify, at some point, the foundation you're using. This can be done in two ways:
1. You can define your own foundation (see above).
2. You can import one from an interpreter.
To specify your request and response foundation, use replace the `client` type in `HttpF client a` or `FreeHttp client m a` to the type signalling your foundation. For example, the http-client, pure, and arbitrary interpreters use `HttpClient`, `PureClient`, and `ArbitraryClient` respectively.