(TK-27) Allow user to manage clients explicitly

This PR will allow the user to explicitly create instances of a sync or async client, and then use those clients for multiple http requests. All the previous APIs remain intact; if the user uses the old http request functions, things will behave as they did before (i.e., it will create a new client and close it once the response comes in).
We have these defaults hard-coded in two different places now.  We should try to figure out a way to refactor this to prevent that.  Maybe the first signature of `request` should just pass in a `nil` for the value of the `client` argument when it calls into the second signature, and the second signature can do all of the argument coercion (split up the `RawUserRequestOptions` map into one instance of `RequestOptions` and one instance of `ClientOptions`).  Then it could do something like:

```clj
(let [client (or client (create-default-client client-options))]
   ...)
```
Don't have my heart set on that exact pattern, happy to discuss / consider other options, but would like to dry it up.

Also, we should probably add some docstrings to the schemas to make them more clear; I should have done this myself, but going through that exercise might make it more clear to you what the various function signatures should look like.  The key ones:

`RawUserRequestOptions`: this should only be used at the edges of the API when we are dealing with direct input from the user.  In this one we have to support lots of optional keys and maybe nils and such, which we don't want to allow to flow too much further into the system.

`UserRequestOptions`: This is basically just a cleaned-up version of `RawUserRequestOptions`; so after we've validated the input from the user and merged in defaults, we have a representation of the options that the user passed us that no longer needs to have as many optional keys in the schema, etc.
It should also be the case that this schema is basically just a composition of `RequestOptions` and `ClientOptions`.

`ClientOptions`: a subset of the `UserRequestOptions` that has to do with instantiating / managing a client.

`RequestOptions`: the remaining subset of `UserRequestOptions`, which has to do with configuration / settings for an individual request.

We can also rename any of those if we think the names aren't clear enough, but conceptually I think those are probably the right units to break the schemas into.