# Criando o cliente da Marvel

Vamos lá mais uma vez. Para termos a conexão com um serviço, precisamos criar essa conexão. Aqui estamos chamando ele de Client e vivera no contexto de integrações. Criaremos o arquivo `lib/coffee_shop/integrations/marvel_comics/client.ex` utilizando o mesmo padrão do cliente do café já criado.&#x20;

Iremos decompor essa chamada do tesla para dentro de nosso novo modulo utilizando os padrões estabelecidos nos capitulos anteriores

```elixir
Tesla.get("https://gateway.marvel.com/v1/public/comics?apikey=12345&hash=7EE341DFFE88E697114117AA51E1A210&ts=1")
```

* Utilizaremos uma função privada para configurar nosso cliente Tesla de forma práticas para os testes.
* Colocaremos a url base em um função isolada, decidindo chamar ela de `https://gateway.marvel.com/v1/public` uma vez que utilizaremos sempre essa base.
* Criaremos uma função publica que fara a requisição

{% code title="lib/coffee\_shop/integrations/marvel\_comics/client.ex" lineNumbers="true" %}

```elixir
defmodule CoffeeShop.Integrations.MarvelComics.Client do
   def comics(opts \\ []) do
    base_url = Keyword.get(opts, :base_url, base_url())

    opts
    |> new_client()
    |> Tesla.get("#{base_url}/v1/public/comics")
  end

  defp new_client(_opts) do
    middlewares = []

    Tesla.client(middlewares)
  end

  defp base_url() do
    "https://gateway.marvel.com"
  end
end

```

{% endcode %}

Essa é a cara base. Precisamos de uma teste para ele.

<pre class="language-elixir" data-title="test/coffee_shop/integrations/marvel_comics/client_test.exs" data-line-numbers><code class="lang-elixir">defmodule CoffeeShop.Integrations.MarvelComics.ClientTest do
  use ExUnit.Case

  alias CoffeeShop.Integrations.MarvelComics.Client

  setup do
    bypass = Bypass.open(port: 3000)
    {:ok, bypass: bypass}
  end

  describe "comics/0" do
    test "respond a list of comics", %{bypass: bypass} do
      response = ""

      Bypass.expect_once(bypass, "GET", "/v1/public/comics", fn conn ->
        assert %{
<strong>          "apiKey" => _,
</strong><strong>          "hash" => _,
</strong><strong>          "ts" => _
</strong>        } = conn.query_params

        Plug.Conn.resp(conn, 200, response)
      end)

      opts = [
        base_url: "http://localhost:3000"
      ]

      assert {:ok, response} = Client.comics(opts)
      assert response.status == 200
    end
  end
end

</code></pre>

Nesse teste, queremos garantir que a requisição chamada é do recurso que queremos. Também queremos garantir que os parâmetros *hash*, *api\_key* e *ts* estão sendo enviados juntos.

```
mix test test/coffee_shop/integrations/marvel_comics/client_test.exs
```

<pre class="language-elixir"><code class="lang-elixir">> mix test test/coffee_shop/integrations/marvel_comics/client_test.exs                                                                                                                                                                main [df2d2e3] modified untracked
Compiling 1 file (.ex)
....
16:33:14.917 [error] #PID&#x3C;0.407.0> running Bypass.Plug (connection #PID&#x3C;0.406.0>, stream id 1) terminated
Server: localhost:3000 (http)
Request: GET /v1/public/comics
** (exit) an exception was raised:
    ** (ExUnit.AssertionError) 

match (=) failed
code:  assert %{"apiKey" => _, "hash" => _, "ts" => _} = conn.query_params
<strong>left:  %{"apiKey" => _, "hash" => _, "ts" => _}
</strong><strong>right: %{}
</strong>
        test/coffee_shop/integrations/marvel_comics/client_test.exs:16: anonymous fn/1 in CoffeeShop.Integrations.MarvelComics.ClientTest."test comics/0 respond a list of comics"/1
        (bypass 2.1.0) lib/bypass/plug.ex:14: Bypass.Plug.call/2
        (plug_cowboy 2.7.1) lib/plug/cowboy/handler.ex:11: Plug.Cowboy.Handler.init/2
        (cowboy 2.12.0) /root/code/study/api/coffee_shop/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
        (cowboy 2.12.0) /root/code/study/api/coffee_shop/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3
        (cowboy 2.12.0) /root/code/study/api/coffee_shop/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3
        (stdlib 5.0.2) proc_lib.erl:241: :proc_lib.init_p_do_apply/3


  1) test comics/0 respond a list of comics (CoffeeShop.Integrations.MarvelComics.ClientTest)
     test/coffee_shop/integrations/marvel_comics/client_test.exs:12
     Assertion with == failed
     code:  assert response.status == 200
     left:  500
     right: 200
     stacktrace:
       test/coffee_shop/integrations/marvel_comics/client_test.exs:30: (test)
</code></pre>

Como vimos na leitura do endpoint, precisamos enviar os três parâmetros para conseguir realizar a chamada. Vamos adiciona-los.

Para adicionar `query_params`, *Tesla* possui um [middleware ](https://hexdocs.pm/tesla/Tesla.Middleware.Query.html)que facilita o trabalho para nós. Vamos usa-lo.

<pre class="language-elixir" data-title="lib/coffee_shop/integrations/marvel_comics/client.ex" data-line-numbers><code class="lang-elixir">defmodule CoffeeShop.Integrations.MarvelComics.Client do
  def comics(opts \\ []) do
    base_url = Keyword.get(opts, :base_url, base_url())

    opts
    |> new_client()
    |> Tesla.get("#{base_url}/v1/public/comics")
  end

  defp new_client(_opts) do
    middlewares = [
<strong>      {Tesla.Middleware.Query, [apikey: "12345", hash: "7EE341DFFE88E697114117AA51E1A210", ts: 1]}
</strong>    ]

    Tesla.client(middlewares)
  end

  defp base_url() do
    "https://gateway.marvel.com"
  end
end

</code></pre>

Decidimos seguir o mesmo padrão adotado no cliente do café e tiramos proveito disso. Basta adicionar o middleware direto na criação do *Tesla.client*. Com isso, podemos rodar os teses novamente.

```
mix test test/coffee_shop/integrations/marvel_comics/client_test.exs
```

```elixir
> mix test test/coffee_shop/integrations/marvel_comics/client_test.exs                                                                                                                         main [df2d2e3] modified untracked
.
Finished in 0.1 seconds (0.00s async, 0.1s sync)
1 test, 0 failures
```

Com isso garantimos que estamos passando todos os dados que precisamos para realizar a requisição.&#x20;


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://consumindo-apis-com-elixir.cafecomelixir.com.br/compondo-integracoes/marvel-api/criando-o-cliente-da-marvel.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
