Lendo o endpoint de Comics
A Marvel API nos disponibiliza alguns recursos legais, como obter personagens, historias em quadrinho, eventos, séries, entre outros.
Para ver todos os endpoints, só acessar o link da documentação e teremos ali uma lista completa dos recursos e como devemos montar nossas requisições.
Em nosso estudo, utilizarei a listagem de Comics (revistas em quadrinhos)
Vamos extrair as informações para conseguir realizar a requisição igual como fizemos em nosso serviço de cafés quentes.
Olhando apenas o básico temos essa estrutura
GET https://<url_base>/v1/public/comics
Temos aqui
Verbo
GET
Recurso
/v1/public/comics
URL base
?
Mas esta faltando a URL base de nossa requisição. Para essa informação, podemos acessar o General API Information. e veremos que nossa base é https://gateway.marvel.com/
Verbo
GET
Recurso
/v1/public/comics
URL base
https://gateway.marvel.com
Podemos agora montar nossa requisição e testala com o Tesla.
GET https://gateway.marvel.com/v1/public/comics
Convertendo
Tesla.get("https://gateway.marvel.com/v1/public/comics")
Podemos acessar nosso terminal iterativo e testar a requisição
iex -S mix
Tesla.get("https://gateway.marvel.com/v1/public/comics")
iex(1)> Tesla.get("https://gateway.marvel.com/v1/public/comics")
{:ok,
%Tesla.Env{
method: :get,
url: "https://gateway.marvel.com/v1/public/comics",
query: [],
headers: [
{"connection", "keep-alive"},
{"date", "Wed, 08 May 2024 17:57:08 GMT"},
{"content-length", "68"},
{"content-type", "application/json; charset=utf-8"}
],
body: "{\"code\":\"MissingParameter\",\"message\":\"You must provide a user key.\"}",
status: 409,
opts: [],
__module__: Tesla,
__client__: %Tesla.Client{fun: nil, pre: [], post: [], adapter: nil}
}}
Aqui temos nosso primeiro problema. Mesmo a API sendo publica, temos controle de quem está acessando. Nesse caso ele avisa que precisamos de um chave de usuário. E foi para isso que criamos uma conta na Marvel.
Acesse sua conta de desenvolvedor e iremos encontrar a chave necessária. Sua API Key é sua chave pública. Marquei de amarelo.
Vou nomear a minha como 12345, para facilitar o entendimento.
Verbo
GET
Recurso
/v1/public/comics
URL base
https://gateway.marvel.com
Api Key
12345
Vamos atualizar nossa chamada com o Tesla. Para passar esse dado, utilizaremos query params.
Tesla.get("https://gateway.marvel.com/v1/public/comics?apikey=12345")
iex(3)> Tesla.get("https://gateway.marvel.com/v1/public/comics?apikey=d3f934e3c9ccb6de467674e4fc7a3ead")
{:ok,
%Tesla.Env{
method: :get,
url: "https://gateway.marvel.com/v1/public/comics?apikey=d3f934e3c9ccb6de467674e4fc7a3ead",
query: [],
headers: [
{"connection", "keep-alive"},
{"date", "Wed, 08 May 2024 18:06:59 GMT"},
{"content-length", "64"},
{"content-type", "application/json; charset=utf-8"}
],
body: "{\"code\":\"MissingParameter\",\"message\":\"You must provide a hash.\"}",
status: 409,
opts: [],
__module__: Tesla,
__client__: %Tesla.Client{fun: nil, pre: [], post: [], adapter: nil}
}}
Passamos do problema da user key. Mas caímos agora no problema do hash.
O hash na API da Marvel é uma encriptação simples usando MD5 que utiliza os dados
TS
Uma string que servirá para termos unicidade nas requisições. Cada requisição deve ter um valor diferente.
Chave Publica
Que chamamos acima de api key
Chave privada
Uma chave extra para realizar a decrypt. Basicamente, a chave para abrir.
As chaves encontramos na conta de de desenvolvedor.
Marquei em amarelo a publica e rosa a privada.

Utilizaremos como TS, por hora, o numero 1. Simplesmente para seguir com os estudos.
Como chave privada, demonstrarei como 88888.
A regra para o hash é:
<TS>+<chave_privada>+<chave_publica>
Podemos criar isso pelo elixir, entrando no modo iterativo
:crypto.hash(:md5, "11234588888") |> Base.encode16()
iex(1)> :crypto.hash(:md5, "11234588888") |> Base.encode16()
"7EE341DFFE88E697114117AA51E1A210"
Vamos agora pegar esse valor e adicionar a nossa query param. Também devemos colocar o valor de TS em nosso query o mesmo informado na criação do hash.
Tesla.get("https://gateway.marvel.com/v1/public/comics?apikey=12345&hash=7EE341DFFE88E697114117AA51E1A210&ts=1")
iex(1)> Tesla.get("https://gateway.marvel.com/v1/public/comics?apikey=12345&hash=7EE341DFFE88E697114117AA51E1A210&ts=1")
{: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}
}}
Pronto, estamos com todo acesso necessário para utilizar a API da Marvel. Bora escrever nosso cliente.
Atualizado
Isto foi útil?