Quando desenvolvemos uma API, não basta apenas devolver os dados corretos no formato JSON; também precisamos informar ao cliente (seja um navegador, aplicativo mobile ou outro servidor) se a requisição foi bem-sucedida ou se ocorreu algum erro. Fazemos isso através dos Status Codes HTTP (Códigos de Status).
Os códigos de status HTTP são números de três dígitos organizados em cinco categorias principais. Eles servem como uma resposta rápida e padronizada do servidor sobre o resultado de um pedido. Por exemplo, quando você acessa uma página que não existe, o famoso erro 404 Not Found é um código de status.
Abaixo estão listados os códigos de status definidos pelo protocolo HTTP, separados por suas respectivas famílias:
| Código | Nome Padrão | Significado / Quando usar |
|---|---|---|
| 1xx: Respostas Informativas (A requisição foi recebida e o processo continua) | ||
| 100 | Continue | O servidor recebeu os cabeçalhos da requisição e o cliente pode continuar. |
| 101 | Switching Protocols | O servidor aceita a mudança de protocolo solicitada pelo cliente (Ex: mudança para WebSocket). |
| 102 | Processing | O servidor recebeu a requisição e está processando, mas nenhuma resposta está pronta ainda. |
| 103 | Early Hints | Retorna alguns cabeçalhos de resposta antes da mensagem HTTP final. |
| 2xx: Sucesso (A ação foi recebida, compreendida e aceita com sucesso) | ||
| 200 | OK | A requisição foi bem-sucedida. Padrão para consultas (GET) de sucesso. |
| 201 | Created | A requisição foi bem-sucedida e um novo recurso foi criado (Muito usado em POST). |
| 202 | Accepted | A requisição foi aceita para processamento, mas o processamento não foi concluído. |
| 203 | Non-Authoritative Information | A resposta veio de uma cópia de terceiros e não diretamente do servidor original. |
| 204 | No Content | A requisição foi bem-sucedida, mas não há conteúdo para retornar (Muito usado em DELETE). |
| 205 | Reset Content | Informa ao cliente para reiniciar a visualização que enviou a requisição (Ex: limpar formulário). |
| 206 | Partial Content | O servidor está enviando apenas parte do recurso devido a um cabeçalho de intervalo do cliente. |
| 3xx: Redirecionamento (Ações adicionais precisam ser tomadas para completar a requisição) | ||
| 300 | Multiple Choices | A requisição tem mais de uma resposta possível e o cliente deve escolher uma delas. |
| 301 | Moved Permanently | A URL do recurso requerido foi alterada permanentemente. A nova URL é informada na resposta. |
| 302 | Found (Moved Temporarily) | O recurso requerido foi movido temporariamente para uma URL diferente. |
| 303 | See Other | O servidor direciona o cliente para obter o recurso solicitado em outra URL usando uma requisição GET. |
| 304 | Not Modified | O recurso não mudou desde a última requisição. O cliente pode usar sua versão em cache. |
| 307 | Temporary Redirect | O servidor direciona o cliente a obter o recurso em outra URL, mas o cliente deve manter o método original. |
| 308 | Permanent Redirect | O recurso foi permanentemente movido para outra URL, exigindo que o método original seja mantido. |
| 4xx: Erros do Cliente (A requisição contém sintaxe incorreta ou não pode ser processada) | ||
| 400 | Bad Request | A requisição está malformada ou possui parâmetros inválidos que o servidor não entende. |
| 401 | Unauthorized | O cliente precisa se autenticar (fazer login) para obter a resposta solicitada. |
| 402 | Payment Required | Código reservado para uso futuro. Originalmente criado para sistemas de pagamento digital. |
| 403 | Forbidden | O cliente é autenticado, mas não tem permissão de acesso ao recurso solicitado. |
| 404 | Not Found | O servidor não conseguiu encontrar o recurso ou rota solicitada. |
| 405 | Method Not Allowed | O método enviado na requisição (Ex: POST) não é permitido na rota acessada. |
| 406 | Not Acceptable | O servidor não possui conteúdo que atenda aos critérios de aceitação enviados pelo cliente. |
| 407 | Proxy Authentication Required | A autenticação precisa ser feita por meio de um proxy antes da requisição prosseguir. |
| 408 | Request Timeout | O servidor desconectou a conexão por tempo de espera esgotado sem receber a requisição completa. |
| 409 | Conflict | A requisição gerou um conflito com o estado atual do servidor (Ex: tentar cadastrar e-mail duplicado). |
| 410 | Gone | O recurso solicitado foi permanentemente deletado e não será colocado de volta. |
| 411 | Length Required | O servidor recusa a requisição porque o campo de cabeçalho 'Content-Length' não foi definido. |
| 412 | Precondition Failed | Uma ou mais condições colocadas nos cabeçalhos da requisição foram avaliadas como falsas. |
| 413 | Payload Too Large | O corpo da requisição é maior do que os limites definidos pelo servidor. |
| 414 | URI Too Long | A URL (URI) solicitada pelo cliente é mais longa do que o servidor aceita processar. |
| 415 | Unsupported Media Type | O formato de mídia dos dados enviados não é suportado pelo servidor (Ex: enviar XML onde se espera JSON). |
| 416 | Range Not Satisfiable | O intervalo especificado pelo campo de cabeçalho 'Range' não pode ser atendido pelo servidor. |
| 417 | Expectation Failed | O servidor não pode atender às exigências indicadas pelo campo de cabeçalho 'Expect'. |
| 421 | Misdirected Request | A requisição foi direcionada a um servidor que não é capaz de produzir uma resposta válida. |
| 422 | Unprocessable Entity | A requisição está bem-formada, mas contém erros semânticos (Ex: falha na validação de campos). |
| 425 | Too Early | O servidor não está disposto a arriscar processar uma requisição que pode ser repetida. |
| 426 | Upgrade Required | O servidor se recusa a processar usando o protocolo atual, mas aceitará após upgrade do cliente. |
| 429 | Too Many Requests | O usuário enviou muitas requisição em um curto período de tempo (Limite de taxa esgotado). |
| 431 | Request Header Fields Too Large | O servidor se recusa a processar porque os campos de cabeçalho da requisição são grandes demais. |
| 451 | Unavailable For Legal Reasons | O acesso ao recurso foi bloqueado por motivos legais ou censura governamental. |
| 5xx: Erros do Servidor (O servidor falhou ao processar uma requisição válida) | ||
| 500 | Internal Server Error | O servidor encontrou uma situação inesperada que o impediu de completar a requisição. |
| 501 | Not Implemented | O servidor não possui suporte ou capacidade para o método ou funcionalidade solicitada. |
| 502 | Bad Gateway | O servidor, ao agir como gateway ou proxy, recebeu uma resposta inválida do servidor upstream. |
| 503 | Service Unavailable | O servidor está temporariamente indisponível (por sobrecarga ou manutenção programada). |
| 504 | Gateway Timeout | O servidor agindo como proxy não recebeu uma resposta a tempo de outro servidor interno. |
| 505 | HTTP Version Not Supported | O servidor não suporta a versão do protocolo HTTP utilizada na requisição. |
| 506 | Variant Also Negotiates | Erro de configuração interna onde o recurso selecionado está envolvido em negociação circular. |
| 507 | Insufficient Storage | O servidor não tem o espaço em disco necessário para salvar ou completar a operação. |
| 508 | Loop Detected | O servidor detectou um loop infinito enquanto processava a requisição. |
| 510 | Not Extended | Exige extensões adicionais à requisição para que o servidor possa atendê-la. |
| 511 | Network Authentication Required | O cliente precisa se autenticar na rede para conseguir acesso à internet (Ex: Wi-Fi de hotel). |
No Go, nós controlamos o status da resposta usando o método w.WriteHeader(). O pacote net/http nos fornece constantes amigáveis para não precisarmos decorar os números dos códigos de status. Veja abaixo a atualização do nosso arquivo main.go:
// Pacote principal da aplicação
package main
// Importações
import (
"encoding/json"
"fmt"
"net/http"
)
// Função para retornar um Hello World!
func helloWorld(w http.ResponseWriter, r *http.Request) {
// 1. Definir o cabeçalho informando que a resposta é um JSON
w.Header().Set("Content-Type", "application/json")
// 2. Definir o Status Code Explicitamente
// http.StatusCreated equivale ao código numérico 201
w.WriteHeader(http.StatusCreated)
// 3. Criar JSON mensagem
mensagem := map[string]string{
"mensagem": "Hello World!",
}
// 4. Converter o map para JSON e retornar
json.NewEncoder(w).Encode(mensagem)
}
// Função principal
func main() {
// Rotas
http.HandleFunc("GET /", helloWorld)
// Retornar o funcionamento do servidor
fmt.Println("Servidor em execução no endereço: http://localhost:8080")
// Configurar servidor
http.ListenAndServe(":8080", nil)
}
Atenção: A função w.WriteHeader() deve ser sempre chamada antes do json.NewEncoder(w).Encode(). Se você tentar alterar o status code depois que os dados já começaram a ser enviados para o cliente, o Go emitirá um aviso no terminal e manterá o status padrão 200 (OK).