Fazer requisições e consumir APIs é uma das partes mais importantes de qualquer aplicação frontend. O conhecimento básico do protocolo HTTP e do consumo de APIs é indispensável para um programador, embora muitos não saibam como fazer isso. Nesse artigo você vai aprender sobre o protocolo HTTP/HTTPs os tipos de requisições e respostas, e como consumir APIs na prática em Javascript.

O que é HTTP e HTTPS

O Hypertext Transfer Protocol (HTTP) é um protocolo para transmissão de dados via rede, baseado em uma arquitetura de cliente servidor, ou seja, o cliente faz uma requisição para o servidor, que responde com alguma informação. Por ser o protocolo principal na internet geralmente o papel do cliente fica com o navegador, mas também pode ser desempenhado por outro servidor, um aplicativo mobile, ou até mesmo um programa desktop, em resumo o cliente é o personagem ativo no diálogo enquanto o servidor assume um papel mais passivo se reservando apenas a responder o que lhe perguntam, é como um interrogatório, o cliente é o investigador, que faz as perguntas, já o servidor é o interrogado.

Este protocolo nasceu com a Web, sua primeira versão, HTTP/0.9, era um protocolo extremamente simples: tinha apenas um método (GET), vou explicar melhor os métodos do HTTP mais a frente no texto, e transmitia apenas texto limpo e sem acentos.

O HTTP/1.0 surgiu da necessidade de se transmitir mais do que texto: imagens, vídeos e arquivos binários passaram a ser suportados, além da introdução de novos métodos: POST e HEAD.

O HTTP/1.1, trouce mais métodos ainda além de funcionalidades importantes como cache e proxy.

Sua versão atual é o HTTP/2.0 que além de mais performática também é mais segura.

Já o Hypertext Transfer Protocol Security (HTTPS) é de forma resumida o http sobre um protocolo SSL, o que de forma resumida criptografa partes das informações trocadas através do protocolo, podendo ser considerado uma versão mais segura do HTTP.

Como fazer requisições HTTP com Javascript?

Como o HTTP é um procolo aberto, existem várias implementações diferentes que seguem as especificações do protocolo. Assim como existem várias implementações de servidores HTTP como o Apache e o Nginx, existem também várias implementações de clientes HTTP nas mais diversas linguagens de programação.

Como este artigo é voltado para desenvolvedores Front-End, vou citar as ferramentas do Javascript.

As versões mais novas do Javascript trazem por padrão duas formas de realizar requisições HTTP: o XMLHttpRequest voltado para consumir APIs que retornam XML, e o fetch mais poderoso e adaptável para mais formatos sendo bastante utilizado para consumir APIs JSON.

No entanto, neste artigo vamos utilizar a biblioteca axios por ser muito mais fácil de entender e ter uma grande base de usuários.

No javascript também é possível consumir requisições HTTP que retornem dados em binário, como imagens e vídeos, mas como raramente isso é necessário nesse artigo vou explicar apenas o consumo de APIs, e como atualmente a maioria das APIs usam o formato JSON vamos deixar o XML de lado.

Entendendo as requisições e respostas no HTTP

Antes de começarmos a fazer requisições é interessante saber a estrutura de uma requisição e de uma resposta no HTTP, ambas podem ser divididas em duas partes: cabeçalhos e corpo.

Os cabeçalhos guardam informações acerca de como aquela requisição/resposta deve ser tradada, o formato, se é JSON, se é texto puro, se é uma imagem, sé ouve algum erro, etc.

Já o corpo possui a “carga paga” a informação que se quer transmitir de fato.

Agora que você já conhece a estrutura de uma requisição e de uma resposta vamos à prática:

Abra o console do seu navegador, aqui mesmo nessa página, você so precisa apertar Ctrl + Shift + j, e digitar a seguinte linha de código:

axios.get('https://api.github.com/users/taciossbr')

Você provavelmente recebera uma resposta parecida com isso:

Promisse {<pending>}

Como requisições HTTP acontecem pela internet elas costumam ser demoradas, e por questões de performance o Javascript usa execução assíncrona, não vou explicar isso aqui, async/await é assunto para outro artigo. Então por enquanto vamos apenas passar uma função para o .then apos o axios e o valor recebido por será a resposta da requisição:

axios.get('https://api.github.com/users/taciossbr').then(resp => console.log(resp))

Recomendo fortemente ler esta página da documentação da Mozilla para entender melhor a execução assíncrona do javascript.

Entre agora na aba de Network do console do seu navegador, nela vão estar algumas requisições entre elas a requisição para https://api.github.com/users/taciossbr, este é um endpoint, como costumamos chamar uma URL de uma API, da API do Github que esta retornando meu usuário.

Retorno da API do github com informações osbre o usuário taciossbr

Na imagem acima já conseguimos enxergar algumas coisas interessantes: método e status code.

Métodos e status

O método da requisição é um campo do cabeçalho da requisição que informa para a API a ação que se deseja realizar. Geralmente são verbos.

Existem vários métodos no HTTP, neste artigo vou explicar os seguintes: GET, POST, PUT, PATCH e DELETE, que são os mais utilizados.

Método GET

O mais simples apenas informa que a requisição e uma solicitação para acessar um determinado recurso. Na requisição que acabamos de fazer você solicitou informações sobre o usuário é recebeu uma resposta com status 200, o que significa que está tudo ok e sua requisição foi respondida com sucesso.

Método POST

Digite no seu console o seguinte código:

axios.post("https://api.github.com/gists", {
  "description": "Hello World Example",
  "public": true,
  "files": {
    "hello_world.js": {
      "content": "console.log('hello, world');"
    }
  }
}).then(resp => console.log(resp))

Erro 401

É você recebeu um erro! Mais precisamente um erro de 401, que significa você não acesso a esse recurso. O método POST serve para criar um recurso, então esse endpoint cria um Gist no Github, mas se esse endpoint existe por que o erro? Porque o Github não quer um monte de gente anônima lotando os bancos de dados deles com Gists aleatórios então reservaram esse endpoint apenas para usuários autenticados, em outras palavras você precisa enviar um cabeçalho Authentication para que o Github deixe você usar esse endpoint!

axios.post("https://api.github.com/gists", {
  "description": "Hello World Example",
  "public": true,
  "files": {
    "hello_world.js": {
      "content": "console.log('hello, world');"
    }
  }
}, {headers: { Authorization: `Basic ${btoa('<username>:<password>')}` }})
    .then(resp => console.log(resp))

Aqui esta a sua resposta com status 201 CREATED, seu Gist foi criado com sucesso.

Observação: a função btoa converte a nossa string para base64 por questões de segurança o Github exige isto!

Método PUT vs método ‘PATCH’

O método PUT simplesmente substitui o recurso que você esta acessando, enquanto o método PATCH altera apenas parcialmente.

Vamos alterar o gist que criamos no exemplo anterior:

{
  "description": "Hello World Example",
  "public": true,
  "files": {
    "hello_world.js": {
      "content": "console.log('hello, world');"
    }
  }
}

Se executarmos o seguinte comando:

axios.put("https://api.github.com/gists/<id do gist>", {
  "description": "Hello World Example",
  "public": true,
  "files": {
    "hello_world.py": {
      "content": "print('hello, world')"
    }
  }
}, {headers: { Authorization: `Basic ${btoa('<username>:<password>')}` }})
    .then(resp => console.log(resp))

Ele não vai apagar o arquivo hello_world.js, mas sim adicionar o arquivo hello_world.py, se fosse um método PUT o hello_world.js seria deletado para sempre.

Vale lembrar que esse endpoint da API do Github não aceita requisições do método PUT e que existem muitas APIs que não seguem esse padrão e tratam o PUT como se fosse PATCH, então é bom ficar atento a documentação da API que você estiver consumindo.

Método DELETE

Esse é muito óbvio:

axios.delete("https://api.github.com/gists/<id do gist>",
    {headers: { Authorization: `Basic ${btoa('<username>:<password>')}` }})
    .then(resp => console.log(resp))

Execute o código acima e de adeus ao seu Gist.

Status code da resposta

O status code da resposta indica se a requisição foi respondida com sucesso, e no caso de erro traz mais algumas informações. Já falamos bastante dos status code nesse artigo, mas aqui vão as “famílias” dos status code mais comuns:

  • 100-199: respostas informativas, raramente você terá de tratar esse tipo de status code.
  • 200-299: sucesso!
  • 300-399: redirecionamento.
  • 400-499: erros do cliente, URL errada, dados inválidos, etc.
  • 500-599: erros no servidor, banco de dados caiu, estagiário com acesso a ambiente de produção, etc.

Se quiser saber mais sobre os status codes recomento o HTTP Status Dogs e a Referência da Mozilla.

{% raw %}

{% endraw %}

Fontes

https://pt.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Hist%C3%B3ria

https://tools.ietf.org/html/rfc2616#page-51

https://developer.mozilla.org/pt-BR/docs/Web/HTTP

https://github.com/axios/axios

https://developer.mozilla.org/pt-BR/docs/Web/API/Fetch_API/Using_Fetch

https://developer.mozilla.org/pt-BR/docs/Web/API/XMLHttpRequest/Usando_XMLHttpRequest

https://developer.github.com/v3/gists/

https://developer.github.com/v3/#http-verbs

https://developer.github.com/v3/#authentication