# `Tesla.Client`
[🔗](https://github.com/elixir-tesla/tesla/blob/v1.17.0/lib/tesla/client.ex#L1)

# `adapter`

```elixir
@type adapter() ::
  module() | {module(), any()} | (Tesla.Env.t() -&gt; Tesla.Env.result())
```

# `middleware`

```elixir
@type middleware() :: module() | {module(), any()}
```

# `t`

```elixir
@type t() :: %Tesla.Client{
  adapter: Tesla.Env.runtime() | nil,
  fun: term(),
  post: Tesla.Env.stack(),
  pre: Tesla.Env.stack()
}
```

# `adapter`

```elixir
@spec adapter(t()) :: adapter()
```

Returns the client's adapter in the same form it was provided.
This can be used to copy an adapter from one client to another.

## Examples

    iex> client = Tesla.client([], {Tesla.Adapter.Hackney, [recv_timeout: 30_000]})
    iex> Tesla.Client.adapter(client)
    {Tesla.Adapter.Hackney, [recv_timeout: 30_000]}

# `insert_middleware!`

```elixir
@spec insert_middleware!(t(), middleware(), :before, module()) :: t()
@spec insert_middleware!(t(), middleware(), :after, module()) :: t()
```

Inserts a new middleware before or after a target middleware, preserving the rest of the original client.
Raises if the target middleware is not found.

## Examples

    iex> client = Tesla.client([Tesla.Middleware.JSON])
    iex> new_client = Tesla.Client.insert_middleware!(client, Tesla.Middleware.Logger, :before, Tesla.Middleware.JSON)
    iex> Tesla.Client.middleware(new_client)
    [Tesla.Middleware.Logger, Tesla.Middleware.JSON]

    iex> client = Tesla.client([Tesla.Middleware.JSON])
    iex> new_client = Tesla.Client.insert_middleware!(client, Tesla.Middleware.Logger, :after, Tesla.Middleware.JSON)
    iex> Tesla.Client.middleware(new_client)
    [Tesla.Middleware.JSON, Tesla.Middleware.Logger]

# `middleware`

```elixir
@spec middleware(t()) :: [middleware()]
```

Returns the client's middleware in the same form it was provided.
This can be used to copy middleware from one client to another.

## Examples

    iex> middleware = [Tesla.Middleware.JSON, {Tesla.Middleware.BaseUrl, "https://api.github.com"}]
    iex> client = Tesla.client(middleware)
    iex> Tesla.Client.middleware(client)
    [Tesla.Middleware.JSON, {Tesla.Middleware.BaseUrl, "https://api.github.com"}]

# `put_middleware`

```elixir
@spec put_middleware(t(), [middleware()]) :: t()
```

Returns a new client with the given middleware list, preserving the rest of the original client.

## Examples

    iex> client = Tesla.client([Tesla.Middleware.JSON])
    iex> new_client = Tesla.Client.put_middleware(client, [Tesla.Middleware.Logger])
    iex> Tesla.Client.middleware(new_client)
    [Tesla.Middleware.Logger]

# `replace_middleware!`

```elixir
@spec replace_middleware!(t(), module(), middleware()) :: t()
```

Returns a new client with the target middleware replaced by a new one,
preserving the rest of the original client. Raises if the target middleware is not found.

## Examples

    iex> client = Tesla.client([Tesla.Middleware.JSON, Tesla.Middleware.Logger])
    iex> new_client = Tesla.Client.replace_middleware!(client, Tesla.Middleware.JSON, Tesla.Middleware.Retry)
    iex> Tesla.Client.middleware(new_client)
    [Tesla.Middleware.Retry, Tesla.Middleware.Logger]

# `update_middleware`

```elixir
@spec update_middleware(t(), ([middleware()] -&gt; [middleware()])) :: t()
```

Returns a new client by applying a function to the existing middleware list,
preserving the rest of the original client.

## Examples

    iex> middleware = [{Tesla.Middleware.BaseUrl, "https://api.github.com"}]
    iex> client = Tesla.client(middleware)
    iex> new_client = Tesla.Client.update_middleware(client, &([Tesla.Middleware.JSON] ++ &1))
    iex> Tesla.Client.middleware(new_client)
    [Tesla.Middleware.JSON, {Tesla.Middleware.BaseUrl, "https://api.github.com"}]

# `update_middleware!`

```elixir
@spec update_middleware!(t(), module(), (middleware() -&gt; middleware())) :: t()
```

Returns a new client by applying a function to the first occurrence of the target middleware,
preserving the rest of the original client. Raises if the target middleware is not found.

The function receives the current middleware entry (`module` or `{module, opts}`) and must
return the new entry. Only the first occurrence is updated if the same middleware appears
multiple times.

## Examples

    iex> client = Tesla.client([{Tesla.Middleware.BaseUrl, "https://old.api.com"}])
    iex> new_client = Tesla.Client.update_middleware!(client, Tesla.Middleware.BaseUrl, fn {m, _} -> {m, "https://new.api.com"} end)
    iex> Tesla.Client.middleware(new_client)
    [{Tesla.Middleware.BaseUrl, "https://new.api.com"}]

---

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