8 - Compreendendo e Configurando Status Code HTTP

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).

O que são Status Code?

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.

Tabela de Status Code HTTP

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)
100ContinueO servidor recebeu os cabeçalhos da requisição e o cliente pode continuar.
101Switching ProtocolsO servidor aceita a mudança de protocolo solicitada pelo cliente (Ex: mudança para WebSocket).
102ProcessingO servidor recebeu a requisição e está processando, mas nenhuma resposta está pronta ainda.
103Early HintsRetorna alguns cabeçalhos de resposta antes da mensagem HTTP final.
2xx: Sucesso (A ação foi recebida, compreendida e aceita com sucesso)
200OKA requisição foi bem-sucedida. Padrão para consultas (GET) de sucesso.
201CreatedA requisição foi bem-sucedida e um novo recurso foi criado (Muito usado em POST).
202AcceptedA requisição foi aceita para processamento, mas o processamento não foi concluído.
203Non-Authoritative InformationA resposta veio de uma cópia de terceiros e não diretamente do servidor original.
204No ContentA requisição foi bem-sucedida, mas não há conteúdo para retornar (Muito usado em DELETE).
205Reset ContentInforma ao cliente para reiniciar a visualização que enviou a requisição (Ex: limpar formulário).
206Partial ContentO 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)
300Multiple ChoicesA requisição tem mais de uma resposta possível e o cliente deve escolher uma delas.
301Moved PermanentlyA URL do recurso requerido foi alterada permanentemente. A nova URL é informada na resposta.
302Found (Moved Temporarily)O recurso requerido foi movido temporariamente para uma URL diferente.
303See OtherO servidor direciona o cliente para obter o recurso solicitado em outra URL usando uma requisição GET.
304Not ModifiedO recurso não mudou desde a última requisição. O cliente pode usar sua versão em cache.
307Temporary RedirectO servidor direciona o cliente a obter o recurso em outra URL, mas o cliente deve manter o método original.
308Permanent RedirectO 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)
400Bad RequestA requisição está malformada ou possui parâmetros inválidos que o servidor não entende.
401UnauthorizedO cliente precisa se autenticar (fazer login) para obter a resposta solicitada.
402Payment RequiredCódigo reservado para uso futuro. Originalmente criado para sistemas de pagamento digital.
403ForbiddenO cliente é autenticado, mas não tem permissão de acesso ao recurso solicitado.
404Not FoundO servidor não conseguiu encontrar o recurso ou rota solicitada.
405Method Not AllowedO método enviado na requisição (Ex: POST) não é permitido na rota acessada.
406Not AcceptableO servidor não possui conteúdo que atenda aos critérios de aceitação enviados pelo cliente.
407Proxy Authentication RequiredA autenticação precisa ser feita por meio de um proxy antes da requisição prosseguir.
408Request TimeoutO servidor desconectou a conexão por tempo de espera esgotado sem receber a requisição completa.
409ConflictA requisição gerou um conflito com o estado atual do servidor (Ex: tentar cadastrar e-mail duplicado).
410GoneO recurso solicitado foi permanentemente deletado e não será colocado de volta.
411Length RequiredO servidor recusa a requisição porque o campo de cabeçalho 'Content-Length' não foi definido.
412Precondition FailedUma ou mais condições colocadas nos cabeçalhos da requisição foram avaliadas como falsas.
413Payload Too LargeO corpo da requisição é maior do que os limites definidos pelo servidor.
414URI Too LongA URL (URI) solicitada pelo cliente é mais longa do que o servidor aceita processar.
415Unsupported Media TypeO formato de mídia dos dados enviados não é suportado pelo servidor (Ex: enviar XML onde se espera JSON).
416Range Not SatisfiableO intervalo especificado pelo campo de cabeçalho 'Range' não pode ser atendido pelo servidor.
417Expectation FailedO servidor não pode atender às exigências indicadas pelo campo de cabeçalho 'Expect'.
421Misdirected RequestA requisição foi direcionada a um servidor que não é capaz de produzir uma resposta válida.
422Unprocessable EntityA requisição está bem-formada, mas contém erros semânticos (Ex: falha na validação de campos).
425Too EarlyO servidor não está disposto a arriscar processar uma requisição que pode ser repetida.
426Upgrade RequiredO servidor se recusa a processar usando o protocolo atual, mas aceitará após upgrade do cliente.
429Too Many RequestsO usuário enviou muitas requisição em um curto período de tempo (Limite de taxa esgotado).
431Request Header Fields Too LargeO servidor se recusa a processar porque os campos de cabeçalho da requisição são grandes demais.
451Unavailable For Legal ReasonsO 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)
500Internal Server ErrorO servidor encontrou uma situação inesperada que o impediu de completar a requisição.
501Not ImplementedO servidor não possui suporte ou capacidade para o método ou funcionalidade solicitada.
502Bad GatewayO servidor, ao agir como gateway ou proxy, recebeu uma resposta inválida do servidor upstream.
503Service UnavailableO servidor está temporariamente indisponível (por sobrecarga ou manutenção programada).
504Gateway TimeoutO servidor agindo como proxy não recebeu uma resposta a tempo de outro servidor interno.
505HTTP Version Not SupportedO servidor não suporta a versão do protocolo HTTP utilizada na requisição.
506Variant Also NegotiatesErro de configuração interna onde o recurso selecionado está envolvido em negociação circular.
507Insufficient StorageO servidor não tem o espaço em disco necessário para salvar ou completar a operação.
508Loop DetectedO servidor detectou um loop infinito enquanto processava a requisição.
510Not ExtendedExige extensões adicionais à requisição para que o servidor possa atendê-la.
511Network Authentication RequiredO cliente precisa se autenticar na rede para conseguir acesso à internet (Ex: Wi-Fi de hotel).

Implementando o Status Code em Go

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).