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.
Iremos decompor essa chamada do tesla para dentro de nosso novo modulo utilizando os padrões estabelecidos nos capitulos anteriores
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
Essa é a cara base. Precisamos de uma teste para ele.
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 %{
"apiKey" => _,
"hash" => _,
"ts" => _
} = 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
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
> 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<0.407.0> running Bypass.Plug (connection #PID<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
left: %{"apiKey" => _, "hash" => _, "ts" => _}
right: %{}
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)
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 que facilita o trabalho para nós. Vamos usa-lo.
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.Middleware.Query, [apikey: "12345", hash: "7EE341DFFE88E697114117AA51E1A210", ts: 1]}
]
Tesla.client(middlewares)
end
defp base_url() do
"https://gateway.marvel.com"
end
end
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
> 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.