Status HTTP Fantásticos e Onde Habitam #1 - Entendendo os códigos
Tags: http, rest, internet, webdev
Published: 2020-03-26 14:20:47

_Photo por Joanna Kosinska no Unsplash_

Por mais de 10 anos, trabalhamos com HTTP e APIs seguindo a arquitetura [ReST](http://bit.ly/2IXukYW). A maioria das pessoas pensa que as APIs são apenas interfaces que você pode usar para interagir com algum programa de terceiros e que [ReST](http://bit.ly/2IXukYW) é sobre verbos HTTP, no entanto, a maior parte da comunicação que usamos atualmente pode estar errada apenas porque estamos usando os __status codes__ HTTP incorretos para expressar nossas respostas. E isso pode mudar a vida quando falamos de aplicativos web modernos.

Isso mesmo! Uma API é muito mais expressiva do que simplesmente escrever _GET_ para buscar dados ou _POST_ para criar dados. Essa é a parte da solicitação. E a resposta?

Neste artigo, exploraremos um pouco mais sobre __Status Codes do HTTP__, quando usar cada um deles e suas definições! Então, vamos nessa!

# Sumário

<!-- @import "[TOC]" {cmd="toc" depthFrom=1 depthTo=6 orderedList=false} -->

<!-- code_chunk_output -->

- [Sumário](#sumário)
- [O que são status codes?](#o-que-são-status-codes)
- [Classes e categorias de status codes](#classes-e-categorias-de-status-codes)
- [Por que eu preciso saber disso?](#por-que-eu-preciso-saber-disso)
- [Escolhendo o status code certo para sua API](#escolhendo-o-status-code-certo-para-sua-api)
  - [Status codes mais usados em APIs](#status-codes-mais-usados-em-apis)
    - [200x](#200x)
      - [200 - OK](#200-ok)
      - [201 - Created](#201-created)
    - [300x](#300x)
      - [301 - Moved Permanently](#301-moved-permanently)
      - [302 - Found](#302-found)
    - [400x](#400x)
      - [400 - Bad Request](#400-bad-request)
      - [401 - Unauthorized](#401-unauthorized)
      - [403 - Forbidden](#403-forbidden)
      - [404 - Not Found](#404-not-found)
      - [405 - Method not allowed](#405-method-not-allowed)
      - [429 - Too many requests](#429-too-many-requests)
    - [500x](#500x)
      - [500 - Internal Server Error](#500-internal-server-error)
      - [502 - Bad Gateway](#502-bad-gateway)
      - [503 - Service Unavailable](#503-service-unavailable)
      - [504 - Gateway Timeout](#504-gateway-timeout)
- [Coffee Break!](#coffee-break)

<!-- /code_chunk_output -->


# O que são status codes?

Todos os protocolos que usamos hoje foram definidos e especificados em um documento que chamamos de **R**equest **F**or **C**omments, ou simplesmente RFC, os [Status Codes](http://bit.ly/38ZENhl) são definidos junto com o próprio protocolo HTTP dentro da [RFC2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html), o documento que define o que é HTTP/1.1, mais especificamente, na seção 10. Eles também são definidos na seção 6 da [RFC7231](https://tools.ietf.org/html/rfc7231#section-6) sobre a semântica do HTTP/1.1. Eles são um código numérico que varia de 100 até mais ou menos 500 e visam tornar a resposta HTTP mais significativa para o cliente.

Legal, citamos toda a história da Internet apenas para obter uma definição, certo? Mas o que isso significa? Sempre que clicamos em um botão e enviamos uma solicitação para um aplicativo [baseado na arquitetura cliente-servidor](http://bit.ly/2U29ePH), esse aplicativo nos responde com outra resposta HTTP, tanto a solicitação quanto a resposta contém um cabeçalho responsável por fornecer o contexto dessa requisição. Os [status codes](http://bit.ly/38ZENhl) são exibidos a cada resposta em um cabeçalho chamado `Status` (criativo né?), e eles estão lá apenas para nos dar uma pista do que aconteceu com a nossa solicitação depois que ela foi processada.

Na maioria das vezes, os usuários comuns não veem esses [status codes](http://bit.ly/38ZENhl) - a menos que algo dê muito errado - mas para nós, programadores, eles são extremamente valiosos. Por exemplo, toda vez que não conseguimos encontrar um recurso ou uma página da Web, uma página de erro __404__ é apresentada, esse __404__ é o código de status HTTP para __Não encontrado__.

![](https://kinsta.com/wp-content/uploads/2016/08/google-404-1-1.png)

Em resumo, eles nos fornecem mais informações sobre o que está acontecendo e o que aconteceu com a solicitação que fizemos, e são muito valiosos para os front-enders que desejam mostrar as mensagens de status corretas com base nas respostas do servidor.

# Classes e categorias de status codes

Como mencionamos anteriormente, os [Status Codes](http://bit.ly/38ZENhl) são numerados de 100 a 500; no entanto, esse intervalo não é totalmente preenchido; por exemplo, não temos um código de status 174, pois essa separação foi feita para dividir códigos em categorias. Essas categorias são definidas em centenas, cada centena do intervalo HTTP representa uma categoria ou classe diferente:

- __100s__: Códigos informativos, apenas para reconhecer que a solicitação foi recebida e está sendo processada;
- __200s__: Códigos de sucesso, retornados quando tudo foi processado ou entendido corretamente, geralmente, isso significa que o cliente não precisa executar mais nenhuma ação;
- __300s__: Códigos de redirecionamento, o que significa que o cliente deve solicitar esse recurso em outro lugar;
- __400s__: Códigos de erro do cliente, quando o cliente faz besteira;
- __500s__: Códigos de erro do servidor, quando o servidor faz besteira;

# Por que eu preciso saber disso?

[Códigos de status](http://bit.ly/38ZENhl) não são importantes apenas para os programadores, pois precisamos saber o que está acontecendo para podermos realizar validações ou mensagens de erro, mas também são importantes para monitorar a integridade do aplicativo, bem como SEO.

No monitoramento, é mais fácil conhecer a integridade de um aplicativo por seu código de status, por exemplo, se seu site está retornando muitos 404s, provavelmente alguém fez alguma coisa errada e esqueceu de colocar alguma página online; no entanto, se seu aplicativo estiver exibindo um 500, provavelmente está offline e ninguém pode usá-lo. Portanto, é muito mais fácil para a equipe de desenvolvimento depurar um aplicativo quando ele exibe as informações corretas.

Por outro lado, fora do ambiente de desenvolvimento, quando falamos sobre SEO, [códigos de status](http://bit.ly/38ZENhl) são a única maneira de os bots de mecanismos de buscas entenderem o que está acontecendo quando "veem" seu site na Internet. Isso significa que, se você é um robô cego que entende apenas [códigos de status](http://bit.ly/38ZENhl), se uma página continua retornando 404, isso significa que essa página não é muito boa, pois não existe, portanto, sua classificação deve ser menor do que outras páginas que retornam um código de status 200 porque essas, de fato, existem.

Não explicarei isso em muitos detalhes aqui, porque nosso foco está nos [códigos de status](http://bit.ly/38ZENhl) e em seus retornos, mas você pode ler mais sobre isso [neste excelente artigo que usei para referência](https://kinsta.com/blog/http-status-codes/#why-http-status-codes-and-errors-matter-for-search-engine-optimization-seo).

# Escolhendo o status code certo para sua API

Nesta seção, examinaremos __todos__ os [códigos de status](http://bit.ly/38ZENhl) definidos e seus significados, mas faremos de forma diferente. Vamos dividir esta seção em três:

1. Códigos de API mais usados, onde falaremos sobre os códigos que já usamos e como devemos usá-los adequadamente
2. Códigos não tão frequentemente usados, mas devíamos usar mais
3. Outros códigos, nos quais terminaremos o guia, explicando os códigos de status menos usados, o que não significa que sejam inúteis - exceto um

Neste artigo, abordaremos apenas a primeira parte, para que não seja uma leitura muito longa para todos! Mas, nos próximos artigos da série, abordaremos as outras duas partes!

E ilustraremos tudo com [gatos](https://http.cat) e [cachorros](https://httpstatusdogs.com/) para que possamos nos divertir um pouco enquanto fazemos isso!

## Status codes mais usados em APIs

Primeiro de tudo, vamos nos aprofundar nas coisas mais comuns, não haverá muito conteúdo novo aqui, afinal, eles já são mais usados. Então, vamos analisar os mais comuns dos [códigos de status](http://bit.ly/38ZENhl) por classes:

### 200x

#### 200 - OK

![](https://http.cat/200)

Eu acredito que este é o código de status mais comum já retornado...

O __200 OK__ é a resposta padrão para solicitações bem-sucedidas. Geralmente, é isso que estamos esperando ver em qualquer lugar. No entanto, a resposta para esse código deve diferir de um método HTTP para outro, conforme descrito [no RFC7231](https://tools.ietf.org/html/rfc7231#section-6.3.1).

__Quando usá-lo__: Geralmente, há outro Código de Status HTTP que expressaria o que você quer dizer de uma maneira melhor, mas, se você tiver dúvidas sobre qual código HTTP usar e sua resposta for um sucesso, então é 200!

#### 201 - Created

![](https://httpstatusdogs.com/img/201.jpg)

Esse código de status geralmente é usado junto com o método `POST`, pois descreve um recurso que foi criado no servidor após o êxito da solicitação.

- [Dê uma olhada na definição](https://tools.ietf.org/html/rfc7231#section-6.3.2)

__Quando usá-lo:__ Ao criar coisas. Por exemplo, quando você cria um novo usuário no banco de dados, a resposta deve ser 201 com o documento recém-criado como o corpo.

### 300x

#### 301 - Moved Permanently

![](https://httpstatusdogs.com/img/301.jpg)

Usado quando o recurso que você procura foi permanentemente movido para outro local. [Este código de status](https://tools.ietf.org/html/rfc7231#section-6.4.2) geralmente vem junto com outro cabeçalho, informando o local exato para onde o recurso foi movido.

__Quando usá-lo:__ Normalmente usado para redirecionamentos permanentes, por exemplo, um site que possui uma página de índice em `http://contoso.com` e deve ser redirecionado para` http://foo.com`. Mas o problema é que __este código de status deve ser usado apenas com os métodos de solicitação GET ou HEAD__, para todos os outros métodos que devemos usar [308](#308-permanent-redirect)

#### 302 - Found

![](https://httpstatusdogs.com/img/302.jpg)

Apesar do texto "Found" não nos dar muita pista do que se trata, o [código de status 302](https://tools.ietf.org/html/rfc7231#section-6.4.3) é comumente usado por redirecionamentos temporários, informando que o recurso foi movido, mas foi encontrado em outro URI descrito no cabeçalho `Location`.

__Quando usá-lo:__ Principalmente no mesmo caso que o [301](#301-moved-permanently), mas usado em redirecionamentos temporários em que o recurso será encontrado na URL atual novamente. No entanto, temos uma regra: __este código de status deve ser usado apenas com os métodos de solicitação GET ou HEAD__, para todos os outros métodos que devemos usar [307](#307-temporary-redirect)

### 400x

#### 400 - Bad Request

![](https://http.cat/400)

[Este código de status](https://tools.ietf.org/html/rfc7231#section-6.5.1) é a representação oficial da frase "não sei, não me importo". Como ele diz apenas que o servidor encontrou um erro na solicitação do cliente e não conseguiu processá-la. O maior erro da maioria dos desenvolvedores da Web é retornar esse erro __SEMPRE__ que eles encontram uma request que não entendem. O que reduz a quantidade de informações fornecidas ao cliente e, portanto, a expressividade da API.

__Quando usá-lo:__ Quando você já tentou tudo e ainda não conseguiu encontrar o que havia de errado com a solicitação. Caso contrário, use um código de erro mais significativo.

#### 401 - Unauthorized

![](https://http.cat/401)

[O código de status 401](https://tools.ietf.org/html/rfc7235#section-3.1) normalmente é confundido com [403](#403-forbidden), a maior diferença é que, no caso de 401, o cliente ainda não está autenticado, portanto, não pode acessar a página.

__Quando usá-lo:__ Quando um recurso não pode ser acessado devido a __problemas de autenticação__, normalmente usado em páginas de login quando o usuário tenta efetuar login com um usuário ou senha incorretos.

#### 403 - Forbidden

![](https://http.cat/403)

Diferentemente do [401](#401-unauthorized), o [código de status 403](https://tools.ietf.org/html/rfc7231#section-6.5.3) refere-se a um recurso que está fora dos escopos da request por qualquer outro motivo __diferente de autorização__, por exemplo, limitação de escopo.

__Quando usá-lo:__ Geralmente usado quando temos um limite para o que os usuários podem fazer no aplicativo, por exemplo, se eu não sou o administrador, não devo excluir outros usuários, portanto, se tentar fazê-lo, Receberei um erro _403 - Forbidden_. A regra geral é lembrar a seguinte sequência:

- Se eu não sei quem está fazendo a solicitação, é _401 - Unauthorized_
- Se eu sei quem está fazendo a solicitação, mas o usuário não tem permissão para fazer isso, é _403 - Forbidden_

#### 404 - Not Found

![](https://http.cat/404)

[O código de status 404](https://tools.ietf.org/html/rfc7231#section-6.5.4) é o mais familiar para todos, mesmo para aqueles que não são desenvolvedores. É bem simples, o recurso que você estava procurando não pôde ser encontrado neste site.

__Quando usá-lo:__ Quando você não consegue encontrar uma página ou recurso, um caso de uso não tão conhecido é retornar 404 quando uma consulta do tipo _find_ - como `/users/1234`, quando buscamos um único usuário por ID - retorna nulo. Essa é uma boa prática porque o usuário estava procurando por um recurso específico e ele não existe. Por outro lado, se você estiver em uma consulta _search_ - como `/users`, ou seja, uma listagem - onde poderá retornar 0 ou mais resultados, a resposta padrão para "Não há usuários registrados" ou "Lista vazia" seria 200.

#### 405 - Method not allowed

![](https://httpstatusdogs.com/img/405.jpg)

Geralmente, quando não implementamos uma rota, mas ela existe, usamos o [código de status 405](https://tools.ietf.org/html/rfc7231#section-6.5.5). Esse código diz que o método que estamos usando é um método conhecido para o servidor - o que significa que ele pode processá-lo - no entanto, esse recurso específico não o aceita.

__Quando usá-lo:__ Vamos explicar através de um exemplo. Se você possui um `POST /users` e um `GET /users`, mas não possui um `DELETE /users`, se eu tentar disparar um `DELETE /users`, você deve retornar um código de status _405_ para mim, esse código de status geralmente vem com outro cabeçalho chamado `Allow`, declarando quais métodos são permitidos.

#### 429 - Too many requests

![](https://http.cat/429)

O clássico "Você está tentando me derrubar?". [O código de status 429](https://tools.ietf.org/html/rfc6585#section-4) é definido em outra RFC, a RFC-6585, para cabeçalhos HTTP adicionais. Ele afirma que o solicitante enviou muitas solicitações em um determinado período de tempo, é o que chamamos de _rate limiting_.

__Quando usá-lo:__ Esse deve ser o padrão para todas as APIs existentes no mercado que não desejam ser derrubadas por ataques DDoS, mas, como esse não é o caso hoje, o caso de uso mais comum desse código de status é limitar o número de solicitações que um usuário pode fazer antes de ser bloqueado pelo servidor. A maioria dos gateways de API e APIs expostas para usuários finais o usam, como o Twitter, por exemplo, o que permite cerca de 15 solicitações por minuto.

> Além disso, se você quiser fazer rate limiting sozinho, a Azure possui [uma ferramenta muito interessante](http://bit.ly/33qzI0d) que torna isso possível

### 500x

#### 500 - Internal Server Error

![](https://http.cat/500)

O clássico "eu fiz besteira". [Este código de status](https://tools.ietf.org/html/rfc7231#section-6.6.1) é enviado como resposta quando o servidor fez algo errado e não sabe como proceder. Se um usuário estiver vendo isso, seu aplicativo está em mau estado, pois esses códigos de status devem estar visíveis apenas para os desenvolvedores do aplicativo. Front-end deve formatar o erro e mostrar uma mensagem mais amigável.

__Quando usá-lo:__ Quando uma exceção é lançada pelo servidor e não é capturada e você não sabe o que aconteceu, mas sabe que está no servidor. Já vi muitas pessoas usando códigos de status como o 400 para mostrar erros no servidor, isso está errado de várias formas...

#### 502 - Bad Gateway

![](https://httpstatusdogs.com/img/502.jpg)

[Este código de status](https://tools.ietf.org/html/rfc7231#section-6.6.3) destina-se a servidores com proxy. Ele afirma que o servidor que está atuando como gateway ou proxy não pôde concluir a solicitação ou recebeu uma request inválida do cliente.

__Quando usá-lo:__ O programador nunca deve precisar usá-lo manualmente, a menos que você esteja criando uma API proxy ou um servidor proxy; nesse caso, você precisará retornar esta mensagem em vez de [500](#500-internal-server-error) que mencionamos anteriormente.

#### 503 - Service Unavailable

![](https://httpstatusdogs.com/img/503.jpg)

[O código 503](https://tools.ietf.org/html/rfc7231#section-6.6.4) é mais um código de informação do que um erro, uma vez que afirma que o servidor que gerencia as solicitações não está disponível devido a uma sobrecarga ou manutenção programada. No caso deste último, o servidor pode opcionalmente enviar um cabeçalho  `Retry-After` com um período de tempo para que o usuário possa tentar novamente.

__Quando usá-lo:__ Como mencionei nos outros erros de 500x, esse código geralmente não é definido pelos programadores, pois está no código do servidor, a menos que você seja o desenvolvedor de um servidor, neste caso, o caso de uso é muito obvio.

#### 504 - Gateway Timeout

![](https://http.cat/504)

[Este código](https://tools.ietf.org/html/rfc7231#section-6.6.5) é uma variação do código [502](#502-bad-gateway), a diferença é que, em vez de não receber uma solicitação correta, o servidor de origem não enviou a solicitação dentro do prazo esperado.

__Quando usá-lo:__ Esse código só deve ser retornado se você estiver codificando um gateway e o servidor proxy não respondeu à sua solicitação.

# Coffee Break!

Pare por agora! Tome um café enquanto se prepara para a próxima parte desta série, onde falaremos sobre as APIs que não vemos com muita frequência, mas deveríamos.

Não deixe de acompanhar mais do meu conteúdo no [meu blog](https://blog.lsantos.dev/?utm_source=devto&utm_medium=article&utm_campaign=http_1) e se [inscreva na newsletter](https://blog.lsantos.dev/signup?utm_source=devto&utm_medium=article&utm_campaign=http_1) para receber notícias semanais!

Viu algum erro, tem alguma sugestão ou crítica? Deixe seu comentário aqui! Ou então me mande uma mensagem em minhas redes sociais! Todo feedback é bem vindo :D

| [Website](https://lsantos.dev) | [GitHub](https://github.com/khaosdoctor) | [Facebook](https://fb.com/lsantos.dev) | [LinkedIn](https://linkedin.com/in/lhs-santos) | [Twitter](https://twitter.com/_staticvoid)
|---|---|---|---|---