# `Host.HTTP`
[🔗](https://github.com/aaronrussell/beamlet/blob/v0.1.0/lib/host/http.ex#L1)

HTTP requests with Req's arguments, answered with a `Req.Response`.

Each function takes the same arguments as its namesake in `Req`:
`get/2` as `Req.get/2`, `request/2` as `Req.request/2`, a URL or a
keyword list first and options after. Req's documentation describes
the options, and the response's helpers work on the result. A
function returns `{:ok, response}` or `{:error, exception}`; its
bang variant returns the response or raises the exception.

    Host.HTTP.get!("https://api.github.com/repos/elixir-lang/elixir").body["stargazers_count"]

    case Host.HTTP.post("https://example.com/hooks", json: %{event: "deployed"}) do
      {:ok, %Req.Response{status: 200}} -> :ok
      {:ok, response} -> {:error, response.status}
      {:error, exception} -> {:error, Exception.message(exception)}
    end

To stream a large body, pass an `into` function; `into: :self` is
refused. The function receives each chunk and returns
`{:cont, acc}` to go on or `{:halt, acc}` to stop:

    Host.HTTP.get!(url,
      into: fn {:data, chunk}, acc ->
        Host.File.write!("export.csv", chunk, [:append])
        {:cont, acc}
      end
    )

Requests reach the public internet. One to a host that is
loopback, on a private network, link-local or another reserved
address, through a redirect included, comes back as
`{:error, %Host.HTTP.BlockedError{}}`. To call a route your beamlet
serves, use `Host.Router.call/4`, which runs it in your process.

Options that would send a request anywhere but the network, or keep
it on disk, are refused with an `ArgumentError` naming the option:
`plug`, `adapter`, `unix_socket`, `connect_options`, `finch` and
`finch_request`, the disk cache, and `.netrc` credentials. `Req`'s
own functions are not available to your code; these are how
requests leave your beamlet.

# `request`

```elixir
@type request() :: String.t() | URI.t() | keyword()
```

A URL, or a keyword list of options that includes `:url`.

# `result`

```elixir
@type result() :: {:ok, Req.Response.t()} | {:error, Exception.t()}
```

The response, or the exception that ended the request.

# `delete`

```elixir
@spec delete(request(), keyword()) :: result()
```

Makes a DELETE request.

# `delete!`

```elixir
@spec delete!(request(), keyword()) :: Req.Response.t()
```

Like `delete/2`, returning the response or raising.

# `get`

```elixir
@spec get(request(), keyword()) :: result()
```

Makes a GET request, e.g. `get("https://example.com", params: [q: "elixir"])`.

# `get!`

```elixir
@spec get!(request(), keyword()) :: Req.Response.t()
```

Like `get/2`, returning the response or raising.

# `head`

```elixir
@spec head(request(), keyword()) :: result()
```

Makes a HEAD request.

# `head!`

```elixir
@spec head!(request(), keyword()) :: Req.Response.t()
```

Like `head/2`, returning the response or raising.

# `patch`

```elixir
@spec patch(request(), keyword()) :: result()
```

Makes a PATCH request.

# `patch!`

```elixir
@spec patch!(request(), keyword()) :: Req.Response.t()
```

Like `patch/2`, returning the response or raising.

# `post`

```elixir
@spec post(request(), keyword()) :: result()
```

Makes a POST request, e.g. `post(url, json: %{name: "beamlet"})`.

# `post!`

```elixir
@spec post!(request(), keyword()) :: Req.Response.t()
```

Like `post/2`, returning the response or raising.

# `put`

```elixir
@spec put(request(), keyword()) :: result()
```

Makes a PUT request.

# `put!`

```elixir
@spec put!(request(), keyword()) :: Req.Response.t()
```

Like `put/2`, returning the response or raising.

# `request`

```elixir
@spec request(request(), keyword()) :: result()
```

Makes a request with the method in the options, e.g.
`request(url: url, method: :options)`.

The method defaults to GET.

# `request!`

```elixir
@spec request!(request(), keyword()) :: Req.Response.t()
```

Like `request/2`, returning the response or raising.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
