# 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](https://developer.marvel.com/docs) e teremos ali uma lista completa dos recursos e como devemos montar nossas requisições.&#x20;

Em nosso estudo, utilizarei a listagem de Comics (revistas em quadrinhos)

<figure><img src="/files/JYJws4KlyBqbtGRvrUaU" alt=""><figcaption><p><a href="https://developer.marvel.com/docs#!/public/getComicsCollection_get_6">https://developer.marvel.com/docs#!/public/getComicsCollection_get_6</a></p></figcaption></figure>

Vamos extrair as informações para conseguir realizar a requisição igual como fizemos em nosso [serviço de cafés quentes](/construindo-um-cliente-usando-tesla/criando-o-client.md).

Olhando apenas o básico temos essa estrutura

```
GET https://<url_base>/v1/public/comics
```

Temos aqui&#x20;

| **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](https://developer.marvel.com/documentation/getting_started). 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

```elixir
Tesla.get("https://gateway.marvel.com/v1/public/comics")
```

Podemos acessar nosso terminal iterativo e testar a requisição

```
iex -S mix   
```

```elixir
Tesla.get("https://gateway.marvel.com/v1/public/comics")
```

```elixir
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](https://developer.marvel.com/account) e iremos encontrar a chave necessária. Sua API Key é sua chave pública. Marquei de amarelo.&#x20;

<figure><img src="/files/oHY10jNqZ11T9GRJnmCE" alt=""><figcaption><p><a href="https://developer.marvel.com/account">https://developer.marvel.com/account</a></p></figcaption></figure>

Vou nomear a minha como 12345, para facilitar o entendimento.

| **Verbo**    | GET                          |
| ------------ | ---------------------------- |
| **Recurso**  | /v1/public/comics            |
| **URL base** | <https://gateway.marvel.com> |
| A**pi Key**  | 12345                        |

Vamos atualizar nossa chamada com o Tesla. Para passar esse dado, utilizaremos query params.

{% code fullWidth="false" %}

```elixir
Tesla.get("https://gateway.marvel.com/v1/public/comics?apikey=12345")
```

{% endcode %}

<pre class="language-elixir"><code class="lang-elixir">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"}
   ],
<strong>   body: "{\"code\":\"MissingParameter\",\"message\":\"You must provide a hash.\"}",
</strong>   status: 409,
   opts: [],
   __module__: Tesla,
   __client__: %Tesla.Client{fun: nil, pre: [], post: [], adapter: nil}
 }}
</code></pre>

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

| Nome          | Descrição                                                                                                    |
| ------------- | ------------------------------------------------------------------------------------------------------------ |
| 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](https://developer.marvel.com/account).

Marquei em amarelo a <mark style="background-color:yellow;">publica</mark> e rosa a <mark style="background-color:red;">privada</mark>.

<figure><img src="/files/aqTiWyRbm6DovZPOnarY" alt=""><figcaption></figcaption></figure>

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

```elixir
:crypto.hash(:md5, "11234588888") |> Base.encode16()
```

```elixir
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.

{% code fullWidth="false" %}

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

{% endcode %}

<pre class="language-elixir" data-full-width="false"><code class="lang-elixir">iex(1)> Tesla.get("https://gateway.marvel.com/v1/public/comics?apikey=12345&#x26;hash=7EE341DFFE88E697114117AA51E1A210&#x26;ts=1")
{:ok,
 %Tesla.Env{
   method: :get,
   url: "https://gateway.marvel.com/v1/public/comics?apikey=d3f934e3c9ccb6de467674e4fc7a3ead&#x26;ts=1&#x26;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"}
   ],
<strong>   body: "{\"code\":200,\"status\":\"Ok\",\"copyright\":\"© 2024 MARVEL\",\"attributionText\":\"Data provided by Marvel. © 2024 MARVEL\",\"attributionHTML\":\"&#x3C;a href=\\\"http://marvel.com\\\">Data provided by Marvel. © 2024 MARVEL&#x3C;/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&#x26;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&#x26;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" &#x3C;> ...,
</strong>   status: 200,
   opts: [],
   __module__: Tesla,
   __client__: %Tesla.Client{fun: nil, pre: [], post: [], adapter: nil}
 }}
</code></pre>

Pronto, estamos com todo acesso necessário para utilizar a API da Marvel. Bora escrever nosso cliente.&#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/lendo-o-endpoint-de-comics.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.
