Lidando com a resposta
Conseguimos faze a requisição para a API da Marvel. O endpoint que batemos traz uma lista de Quadrinhos. Essa foi a resposta que obtemos:
{:ok,
%Tesla.Env{
method: :get,
url: "https://gateway.marvel.com/v1/public/comics?apikey=d3f934e3c9ccb6de467674e4fc7a3ead&ts=1&hash=1d49870a0631827587878fcff98fa267",
query: [],
headers: [
{"connection", "keep-alive"},
{"date", "Wed, 08 May 2024 18:21:51 GMT"},
{"etag", "60ddd4a67c6e3242fa2560dbb0035b3925d666ef"},
{"content-length", "66553"},
{"content-type", "application/json; charset=utf-8"}
],
body: "{\"code\":200,\"status\":\"Ok\",\"copyright\":\"© 2024 MARVEL\",\"attributionText\":\"Data provided by Marvel. © 2024 MARVEL\",\"attributionHTML\":\"<a href=\\\"http://marvel.com\\\">Data provided by Marvel. © 2024 MARVEL</a>\",\"etag\":\"60ddd4a67c6e3242fa2560dbb0035b3925d666ef\",\"data\":{\"offset\":0,\"limit\":20,\"total\":60239,\"count\":20,\"results\":[{\"id\":82967,\"digitalId\":0,\"title\":\"Marvel Previews (2017)\",\"issueNumber\":0,\"variantDescription\":\"\",\"description\":\"\",\"modified\":\"2019-11-07T08:46:15-0500\",\"isbn\":\"\",\"upc\":\"75960608839302811\",\"diamondCode\":\"\",\"ean\":\"\",\"issn\":\"\",\"format\":\"\",\"pageCount\":112,\"textObjects\":[],\"resourceURI\":\"http://gateway.marvel.com/v1/public/comics/82967\",\"urls\":[{\"type\":\"detail\",\"url\":\"http://marvel.com/comics/issue/82967/marvel_previews_2017?utm_campaign=apiRef&utm_source=25a07f7adccf7328d3153451c26bd992\"}],\"series\":{\"resourceURI\":\"http://gateway.marvel.com/v1/public/series/23665\",\"name\":\"Marvel Previews (2017 - Present)\"},\"variants\":[{\"resourceURI\":\"http://gateway.marvel.com/v1/public/comics/82965\",\"name\":\"Marvel Previews (2017)\"},{\"resourceURI\":\"http://gateway.marvel.com/v1/public/comics/82970\",\"name\":\"Marvel Previews (2017)\"},{\"resourceURI\":\"http://gateway.marvel.com/v1/public/comics/82969\",\"name\":\"Marvel Previews (2017)\"},{\"resourceURI\":\"http://gateway.marvel.com/v1/public/comics/74697\",\"name\":\"Marvel Previews (2017)\"},{\"resourceURI\":\"http://gateway.marvel.com/v1/public/comics/72736\",\"name\":\"Marvel Previews (2017)\"},{\"resourceURI\":\"http://gateway.marvel.com/v1/public/comics/75668\",\"name\":\"Marvel Previews (2017)\"},{\"resourceURI\":\"http://gateway.marvel.com/v1/public/comics/65364\",\"name\":\"Marvel Previews (2017)\"},{\"resourceURI\":\"http://gateway.marvel.com/v1/public/comics/65158\",\"name\":\"Marvel Previews (2017)\"},{\"resourceURI\":\"http://gateway.marvel.com/v1/public/comics/65028\",\"name\":\"Marvel Previews (2017)\"},{\"resourceURI\":\"http://gateway.marvel.com/v1/public/comics/75662\",\"name\":\"Marvel Previews (2017)\"},{\"resourceURI\":\"http://gateway.marvel.com/v1/public/comics/74320\",\"name\":\"Marvel Previews (2017)\"},{\"resourceURI\":\"http://gateway.marvel.com/v1/public/comics/73776\",\"name\":\"Marvel Previews (2017)\"}],\"collections\":[],\"collectedIssues\":[],\"dates\":[{\"type\":\"onsaleDate\",\"date\":\"2099-10-30T00:00:00-0500\"},{\"type\":\"focDate\",\"date\":\"2019-10-07T00:00:00-0400\"}],\"prices\":[{\"type\":\"printPrice\",\"price\":0}],\"thumbnail\":{\"path\":\"http://i.annihil.us/u/prod/marvel/i/mg/b/40/image_not_available\",\"extension\":\"jpg\"},\"images\":[],\"creators\":{\"available\":1,\"collectionURI\":\"http://gateway.marvel.com/v1/public/comics/82967/creators\",\"items\":[{\"resourceURI\":\"http://gateway.marvel.com/v1/public/creators/10021\",\"name\":\"Jim Nausedas\",\"role\":\"editor\"}],\"returned\":1},\"characters\":{\"available\":0,\"collectionURI\":\"http://gateway.marvel.com/v1/public/comics/82967/characters\",\"items\":[],\"returned\":0},\"stories\":{\"available\":2,\"collectionURI\":\"http://gateway.marvel.com/v1/public/comics/82967/stories\",\"items\":[{\"resourceURI\":\"http://gateway.marvel.com/v1/public/stories/183698\",\"name\":\"cover from Marvel Previews (2017)\",\"type\":\"cover\"},{\"resourceURI\":\"http://gateway.marvel.com/v1/public/stories/183699\",\"name\":\"story from Marvel Previews (2017)\",\"type\":\"interiorStory\"}],\"returned\":2},\"events\":{\"available\":0,\"collectionURI\":\"http://gateway.marvel.com/v1/public/comics/82967/events\",\"items\":[],\"returned\":0}},{\"id\":82965,\"digitalId\":0,\"title\":\"Marvel Previews (2017)\",\"issueNumber\":0,\"variantDescription\":\"\",\"description\":\"\",\"modified\":\"2019-08-21T17:11:27-0400\",\"isbn\":\"\",\"upc\":\"75960608839302611\",\"diamondCode\":\"JUL190068\",\"ean\":\"\",\"issn\":\"\",\"format\":\"\",\"pageCount\":152,\"textObjects\":[],\"resourceURI\":\"http://gateway.marvel.com/v1/public/comics/82965\",\"urls\":[{\"type\":\"detail\",\"url\":\"http://marvel.com/comics/issue/82965/marvel_previews_2017?utm_campaign=apiRef&utm_source=25a07f7adccf7328d3153451c26bd992\"}],\"series\":{\"resourceURI\":\"http://gateway.marvel.com/v1/public/series/23665\",\"name\":\"Marvel Previews (2017 - Present)\"},\"variants\":[{\"resourceURI\":\"http://gateway.marvel.com/v1/public/comics/82967\",\"name\":\"Marvel Previews (2017)\"},{\"resourceURI\":\"http://gateway.marvel.co" <> ...,
status: 200,
opts: [],
__module__: Tesla,
__client__: %Tesla.Client{fun: nil, pre: [], post: [], adapter: nil}
}}
A primeira coisa que gosto de fazer, é tirar a resposabilidade da resposta do Tesla e criar um Response nosso. Vamos fazer isso.
lib/coffee_shop/integrations/marvel_comics/response.ex
defmodule CoffeeShop.Integrations.MarvelComics.Response do
defstruct status: :integer, body: :map
def build({:ok, %Tesla.Env{status: status, body: body}}) do
response = %__MODULE__{
status: status,
body: body
}
{:ok, response}
end
end
Ele segue a mesma estrutura do respose do Café. Deixo separado para facilitar tratamentos de resposta para cada integração. Não faz sentido termos a mesma resposta em várias integrações e logo veremos isso. Vamos adicionar em nosso cliente.
lib/coffee_shop/integrations/marvel_comics/client.ex
defmodule CoffeeShop.Integrations.MarvelComics.Client do
alias CoffeeShop.Integrations.MarvelComics.Response
def comics(opts \\ []) do
base_url = Keyword.get(opts, :base_url, base_url())
opts
|> new_client()
|> Tesla.get("#{base_url}/v1/public/comics")
|> Response.build()
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
Precisamos atualizar nosso teste
test/coffee_shop/integrations/marvel_comics/client_test.exs
defmodule CoffeeShop.Integrations.MarvelComics.ClientTest do
use ExUnit.Case
describe "comics/0" do
test "respond a list of comics", %{bypass: bypass} do
# ...
assert {:ok, %Response{status: 200, body: _}} = Client.comics(opts)
end
end
end
mix test test/coffee_shop/integrations/marvel_comics/client_test.exs
> mix test test/coffee_shop/integrations/marvel_comics/client_test.exs
Compiling 1 file (.ex)
.
Finished in 0.1 seconds (0.00s async, 0.1s sync)
1 test, 0 failures
Atualizado