SkillsTecnológicas
Menu
Back-end

API REST: Fundamentos, Métodos HTTP e Boas Práticas

Entenda os fundamentos de uma API REST: recursos, métodos HTTP, status, idempotência, erros, versionamento, segurança e boas práticas de design.

Marcos RodriguesPublicado em 29 de outubro de 2024Atualizado em 19 de agosto de 202616 min de leitura
Clientes web e móvel conectados a recursos e servidores por uma interface de API organizada

Uma API REST bem projetada organiza dados e operações como recursos acessados por URLs, usa a semântica do HTTP de forma previsível e entrega respostas que clientes diferentes conseguem interpretar sem conhecer a implementação interna.

O resultado é um contrato mais simples de integrar, testar, evoluir e observar.

REST não é apenas retornar JSON nem criar rotas com verbos como /buscarUsuario.

É um estilo arquitetural baseado em restrições, entre elas separação entre cliente e servidor, comunicação sem estado, cache, interface uniforme e sistema em camadas.

Na prática, a qualidade também depende de recursos bem modelados, métodos corretos, códigos de status úteis, erros consistentes, autorização e compatibilidade.

Este guia é uma referência prática para quem já conhece a ideia básica de API e quer tomar decisões melhores de design. Se o assunto ainda é novo, leia primeiro o que é API REST e como ela funciona; aqui avançaremos da arquitetura para o contrato e as boas práticas.

API REST em uma frase

Uma API REST expõe recursos por uma interface uniforme e transfere representações desses recursos entre clientes e servidores.

Em vez de cada tela ou consumidor depender de detalhes internos, todos conversam por um contrato estável: identificadores, métodos, cabeçalhos, conteúdo e respostas com significado conhecido.

Imagine uma plataforma de pedidos. O recurso /pedidos representa a coleção; /pedidos/847 identifica um item.

O cliente pode consultar, criar ou alterar representações usando operações HTTP. A URL aponta para o substantivo; o método expressa a intenção.

O que realmente torna uma API REST

REST, sigla de Representational State Transfer, foi descrito por Roy Fielding como um estilo arquitetural para sistemas distribuídos de hipermídia.

O capítulo original sobre REST explica que suas propriedades surgem da combinação de restrições, não da escolha de um formato específico ou framework.

Por isso, “RESTful” não deveria significar apenas “tem endpoints HTTP”. Uma API pode usar JSON, GET e POST e ainda ignorar cache, semântica dos métodos ou identificação consistente de recursos.

Também existem níveis de aderência: muitas APIs comerciais aplicam boa parte das restrições, mas não chegam à hipermídia como motor de estado.

Restrições arquiteturais do REST

As restrições ajudam a explicar por que REST funciona bem em ambientes com clientes variados, intermediários e equipes que evoluem de forma independente.

Elas também revelam os custos: uma interface genérica pode ser menos eficiente para certos casos, e a comunicação sem estado repete informações entre requisições.

Cliente e servidor

A separação cliente-servidor divide responsabilidades. O cliente cuida da experiência e do estado de interação; o servidor governa recursos, regras e persistência.

Aplicativo móvel, painel web e integração de parceiro podem evoluir sem conhecer tabelas, filas ou classes internas, desde que o contrato seja preservado.

Comunicação sem estado

Cada requisição deve carregar as informações necessárias para ser compreendida. “Sem estado” não significa que o servidor não possui banco de dados; significa que ele não depende de contexto de conversa oculto entre duas requisições.

Credenciais, parâmetros e precondições acompanham a operação.

Isso facilita distribuir chamadas entre instâncias, recuperar falhas e observar uma interação isoladamente. O custo é transportar parte do contexto novamente.

Tokens enormes, por exemplo, podem aumentar tráfego e exposição; o desenho precisa equilibrar independência, segurança e eficiência.

Respostas cacheáveis

Uma resposta informa se pode ser reutilizada, por quanto tempo e em quais condições. Cache reduz latência e processamento, mas exige políticas coerentes.

Dados públicos relativamente estáveis podem aceitar reutilização; conteúdo individual ou sensível precisa de controles mais restritos.

Interface uniforme

A interface uniforme é o elemento central: recursos identificáveis, manipulação por representações, mensagens autodescritivas e hipermídia.

Em projetos práticos, isso se traduz em URLs estáveis, métodos com semântica conhecida, tipos de conteúdo declarados, respostas compreensíveis e links quando ajudam o cliente a descobrir ações relacionadas.

Sistema em camadas e código sob demanda

O cliente não precisa saber se conversa diretamente com a origem, um gateway, balanceador, cache ou proxy. Camadas podem aplicar roteamento, segurança e observabilidade sem mudar o contrato.

O artigo sobre proxy reverso com Nginx mostra um exemplo desse papel intermediário.

Código sob demanda é a única restrição opcional: o servidor pode ampliar o cliente enviando código executável.

É comum na Web, mas raro como característica central de APIs de dados. Não é preciso forçá-lo para obter os benefícios das demais restrições.

Como modelar recursos e URLs

Comece pelos conceitos do domínio, não pelas telas nem pelas funções do código.

Clientes, pedidos, produtos e pagamentos são recursos naturais. Use substantivos e hierarquias apenas quando expressarem relacionamento: /clientes/42/pedidos pode listar pedidos daquele cliente, mas /pedidos/847 continua sendo a identidade principal do pedido.

  • prefira /pedidos a /listarPedidos;
  • mantenha convenção consistente de plural, caixa e separadores;
  • use parâmetros de consulta para filtros, ordenação e paginação;
  • não exponha nomes de tabelas ou detalhes acidentais da implementação;
  • evite hierarquias profundas que acoplem a identidade a um caminho instável.

Operações que não se encaixam como CRUD ainda podem ser recursos. Em vez de POST /pedidos/847/cancelar, uma opção é criar POST /pedidos/847/cancelamentos.

Nem sempre existe uma única resposta correta: clareza do domínio e comportamento previsível valem mais que uma regra estética.

Representações, JSON e negociação de conteúdo

Recurso e representação não são a mesma coisa. O pedido é o conceito; o JSON retornado é uma representação de seu estado em determinado momento.

A API pode oferecer outra representação, como CSV ou imagem, sem transformar o recurso em algo diferente.

Content-Type descreve o conteúdo enviado; Accept indica formatos aceitos pelo cliente.

Declarar esses campos evita interpretações implícitas. Datas, valores monetários, identificadores e campos opcionais também precisam de convenções documentadas.

Um JSON sintaticamente válido ainda pode ser semanticamente ambíguo.

Métodos HTTP em uma API REST

O método comunica a intenção da operação. A especificação de semântica HTTP, RFC 9110, define métodos, propriedades como segurança e idempotência, cabeçalhos e códigos de status.

Respeitar essas definições permite que bibliotecas, caches, proxies e pessoas antecipem o comportamento.

GET e HEAD

GET recupera uma representação e não deve causar mudança de estado solicitada pelo cliente.

Métricas e logs podem ocorrer como efeitos colaterais, mas visitar uma URL não pode confirmar compra ou excluir registro. HEAD devolve os mesmos metadados esperados para GET, sem conteúdo da resposta, e é útil para verificar existência ou validade.

POST

POST envia conteúdo para processamento segundo a semântica do recurso.

É comum na criação dentro de uma coleção, como POST /pedidos, quando o servidor escolhe o identificador. Se criar algo, a resposta costuma usar 201 Created e informar a URL em Location.

POST não é idempotente por definição. Se um cliente repetir uma cobrança após perder a resposta, pode criar duplicidade.

Para operações críticas, aceite uma chave de idempotência, guarde o resultado associado e defina prazo e escopo da deduplicação.

PUT e PATCH

PUT cria ou substitui o estado do recurso identificado pelo cliente. A intenção é enviar uma representação completa para aquela URL, e chamadas idênticas devem produzir o mesmo estado desejado.

PATCH aplica uma alteração parcial descrita por um formato de patch; sua idempotência depende do documento e da operação escolhida.

Não trate PUT e PATCH como sinônimos de “atualização total” e “atualização parcial” sem definir campos ausentes, valores nulos e validação concorrente.

O contrato precisa dizer se um campo omitido é preservado, removido ou recebe padrão.

DELETE

DELETE solicita a remoção da associação do recurso com sua URL. O servidor pode apagar dados, arquivá-los ou iniciar um processo assíncrono conforme regras legais e de domínio.

A resposta deve representar o resultado real: 204 No Content quando concluiu sem corpo, 202 Accepted quando apenas aceitou o processamento.

Fluxos coloridos representam diferentes operações e respostas entre um cliente e recursos de uma API
Métodos, recursos e respostas formam um contrato previsível quando cada operação preserva a semântica do HTTP.

Métodos seguros e idempotentes

Um método seguro é essencialmente de leitura: o cliente não solicita mudança de estado. GET, HEAD e OPTIONS são seguros. Idempotência significa que repetir requisições idênticas tem o mesmo efeito pretendido de uma única execução. PUT e DELETE são idempotentes; POST e PATCH não têm essa garantia geral.

Idempotente não significa “a resposta será igual”. Repetir DELETE pode retornar sucesso primeiro e “não encontrado” depois, mas o estado final permanece sem o recurso.

Essa propriedade orienta retentativas: clientes podem repetir operações idempotentes após falha de conexão com risco menor, enquanto operações não idempotentes exigem deduplicação.

Códigos de status HTTP

O status resume o resultado e o corpo fornece detalhes. Escolher sempre 200 obriga o cliente a abrir o JSON para descobrir se houve sucesso.

Também não ajuda trocar cada regra de negócio por um código raro: use um conjunto pequeno, correto e consistente.

StatusUso típico
200 OKConsulta ou atualização concluída com representação.
201 CreatedNovo recurso criado; normalmente acompanha Location.
202 AcceptedProcessamento aceito, mas ainda não concluído.
204 No ContentSucesso sem corpo de resposta.
400 Bad RequestRequisição malformada ou inválida de modo geral.
401 UnauthorizedAutenticação ausente ou inválida.
403 ForbiddenIdentidade reconhecida, mas sem permissão.
404 Not FoundRecurso não encontrado ou ocultado por política.
409 ConflictConflito com o estado atual, como duplicidade.
422 Unprocessable ContentConteúdo compreendido, porém semanticamente inválido.
429 Too Many RequestsLimite de requisições excedido.
500 Internal Server ErrorFalha inesperada do servidor.
503 Service UnavailableServiço temporariamente indisponível.

Não exponha stack trace ou detalhes internos em respostas 5xx. Inclua um identificador de correlação que permita encontrar logs sem revelar segredos.

Para 429 e indisponibilidade temporária, cabeçalhos como Retry-After ajudam o cliente a reagir com backoff em vez de aumentar a sobrecarga.

Cabeçalhos de requisição e resposta

Cabeçalhos transportam metadados e controles sem misturá-los ao domínio. Authorization apresenta credenciais; Content-Type descreve o corpo; Accept negocia representação; Cache-Control orienta reutilização; ETag identifica uma versão; Location aponta para o recurso criado.

Evite criar cabeçalhos proprietários para informações que já possuem padrão.

Quando um cabeçalho customizado for necessário, documente semântica, formato e intermediários envolvidos.

Dados essenciais à regra de negócio geralmente pertencem ao corpo ou ao recurso, não a um campo invisível inventado.

Erros consistentes com Problem Details

Uma API previsível usa a mesma estrutura para erros equivalentes. O cliente precisa identificar o tipo do problema, apresentar uma mensagem adequada, associar falhas a campos e decidir se pode tentar novamente.

Alterar o formato conforme o endpoint multiplica condicionais e dificulta observabilidade.

A RFC 9457, Problem Details for HTTP APIs, define um formato legível por máquinas, normalmente servido como application/problem+json. Campos como type, title, status, detail e instance oferecem uma base extensível.

{
  "type": "https://api.exemplo.com/problemas/estoque-insuficiente",
  "title": "Estoque insuficiente",
  "status": 409,
  "detail": "A quantidade solicitada não está disponível.",
  "instance": "/pedidos/847"
}

detail pode ajudar uma pessoa, mas clientes não devem depender de sua frase exata. Use o tipo ou um código estável para decisões automáticas.

Não inclua dados pessoais, consultas SQL, caminhos internos ou tokens no erro.

Paginação, filtros e ordenação

Coleções crescem; retornar tudo degrada banco, rede, memória e experiência. Defina limite padrão, máximo permitido e metadados ou links para continuar.

Paginação por página e deslocamento é simples, mas pode repetir ou pular itens quando a coleção muda. Cursores são mais estáveis em fluxos grandes e atualizados com frequência.

Filtros devem ter nomes e operadores documentados. Ordenação precisa de critério determinístico, geralmente com identificador como desempate. Se created_at empata, ordenar também por id evita oscilações. Não transforme uma query string em linguagem arbitrária que contorne autorização ou produza consultas sem limite.

Versionamento e compatibilidade

Versionar é uma estratégia para mudanças incompatíveis, não uma licença para quebrar clientes.

Adicionar campo opcional costuma ser compatível; remover, renomear, mudar tipo ou reinterpretar valor pode exigir nova versão e migração.

Antes de alterar, identifique consumidores, anuncie depreciação e acompanhe uso.

A versão pode aparecer na URL, como /v2/pedidos, em cabeçalho ou no tipo de mídia.

A URL é explícita e simples de operar; cabeçalhos mantêm identificadores mais limpos, porém reduzem visibilidade.

Escolha uma convenção, documente e não misture mecanismos sem necessidade.

Compatibilidade também depende do comportamento. Trocar a ordenação padrão, tornar um campo obrigatório ou reduzir um limite pode quebrar integrações sem mudar schema.

Testes de contrato e telemetria ajudam a descobrir impactos antes da remoção.

Cache e requisições condicionais

Cache não é apenas uma otimização de CDN. O servidor pode informar frescor com Cache-Control; o cliente pode validar uma representação com ETag e If-None-Match.

Se nada mudou, 304 Not Modified evita transferir novamente o conteúdo.

Validadores também evitam sobrescrita concorrente. Um cliente lê um pedido com ETag, altera localmente e envia If-Match.

Se outra operação mudou o recurso, o servidor rejeita a precondição em vez de apagar silenciosamente a atualização mais recente.

Defina cache considerando autorização e privacidade. Uma resposta individual não deve parar em cache compartilhado por acidente.

Campos Vary, escopo público ou privado e proibição de armazenamento precisam refletir como a representação foi produzida.

Autenticação, autorização e segurança

Autenticação confirma uma identidade; autorização decide o que ela pode fazer sobre cada recurso.

Validar somente que o token existe é insuficiente. Se um usuário troca /pedidos/847 por /pedidos/848, o servidor deve verificar se ele pode acessar o segundo objeto.

O OWASP API Security Top 10 reúne riscos como autorização quebrada em objetos e funções, consumo irrestrito de recursos, fluxos de negócio sensíveis expostos e inventário inadequado.

O checklist deve virar controles concretos, não apenas uma leitura antes do lançamento.

  • use HTTPS e valide tokens, emissor, audiência e expiração;
  • autorize por objeto e ação, aplicando menor privilégio;
  • valide tamanho, tipo e formato de entradas;
  • limite requisições, concorrência e custo por operação;
  • proteja segredos fora do código e rotacione credenciais;
  • registre eventos úteis sem gravar tokens ou dados sensíveis;
  • mantenha inventário de versões, hosts e endpoints ativos.

Credenciais de banco, chaves e tokens de serviço não pertencem ao repositório.

O guia sobre Dotenv e variáveis de ambiente explica o limite entre configuração local e gerenciamento seguro em produção.

Documentação com OpenAPI

Documentação útil descreve operações, parâmetros, autenticação, schemas, respostas, erros e exemplos.

O contrato deve permitir que uma equipe integre sem ler o código do servidor. Inclua também limites, idempotência, paginação, compatibilidade e comportamento assíncrono.

A especificação OpenAPI oferece um formato padrão para descrever APIs HTTP. Ela pode alimentar documentação interativa, validação, mocks, geração de clientes e testes.

Ainda assim, um arquivo válido não garante bom design: nomes vagos e schemas incompletos continuam vagos em YAML.

Tratar o contrato antes da implementação reduz decisões contraditórias. Para uma visão do ciclo completo — planejamento, construção, deploy e operação — consulte o guia de desenvolvimento de APIs.

Testes e observabilidade

Teste o comportamento observável, não apenas funções internas. Testes unitários cobrem regras; integração valida banco, filas e adaptadores; contrato verifica schema e semântica; ponta a ponta percorre fluxos críticos.

Casos negativos importam: token inválido, objeto de outro usuário, payload grande, condição de corrida e dependência indisponível.

Automatize validações no pipeline para impedir que mudança incompatível chegue sem aviso.

O artigo sobre CI/CD com segurança mostra como integrar testes e controles ao processo de entrega.

Em produção, acompanhe taxa de requisições, latência, erros, saturação e métricas do negócio. Logs estruturados e traces devem carregar identificadores de correlação, não credenciais.

Alertas precisam distinguir uma falha isolada de tendência que afeta consumidores.

Equipe acompanha testes automatizados, controles de acesso e monitoramento de serviços de uma API
Testes, autorização, limites de uso e observabilidade precisam acompanhar a API desde o contrato até a produção.

Exemplo de contrato para uma API de pedidos

Considere um fluxo simples. POST /pedidos recebe itens, endereço e uma chave de idempotência. Se válido, cria o pedido, responde 201 e envia Location: /pedidos/847. A representação contém identificador, estado, itens, totais, moeda e datas em formato definido.

GET /pedidos/847 exige identidade autorizada e pode responder com ETag. PATCH /pedidos/847 aceita apenas alterações permitidas enquanto o pedido está aberto e usa If-Match para evitar conflito.

Tentar mudar um pedido já enviado retorna 409 com Problem Details específico.

POST /pedidos/847/cancelamentos cria uma solicitação de cancelamento. Se o processamento for assíncrono, retorna 202 e aponta para o recurso que representa o andamento.

Dessa forma, o contrato não finge que uma operação longa terminou no instante da requisição.

Esse exemplo conecta recursos, métodos, status, idempotência, precondições e erros.

A linguagem ou framework pode mudar sem alterar o significado externo. É esse desacoplamento que torna uma API sustentável.

Erros comuns em APIs REST

  • Usar verbos em todas as URLs: mistura ação e identidade, produzindo rotas inconsistentes.
  • Responder sempre 200: esconde semântica de erro, criação, processamento e ausência de conteúdo.
  • Confundir sem estado com ausência de persistência: REST não impede bancos, cache ou filas.
  • Ignorar idempotência: retentativas podem duplicar cobrança, pedido ou mensagem.
  • Autorizar apenas no nível da rota: um usuário autenticado pode acessar objetos que não lhe pertencem.
  • Retornar listas ilimitadas: volume cresce até afetar banco e clientes.
  • Expor detalhes internos: stack traces e schemas físicos aumentam risco e acoplamento.
  • Versionar tudo cedo demais: versões paralelas elevam custo sem substituir disciplina de compatibilidade.
  • Gerar documentação e não mantê-la: contrato divergente é pior que documentação assumidamente incompleta.

REST não é a melhor escolha automática para todo sistema. Consultas flexíveis, eventos, streaming ou comunicação interna de baixa latência podem favorecer outros estilos.

O comparativo API REST vs. GraphQL ajuda a avaliar uma alternativa para consultas orientadas pelo cliente.

Checklist de uma API REST consistente

  1. Os recursos representam conceitos do domínio e possuem identificadores estáveis?
  2. URLs usam substantivos e parâmetros com convenções coerentes?
  3. Métodos HTTP preservam segurança e idempotência esperadas?
  4. Status e cabeçalhos descrevem o resultado sem depender do corpo?
  5. Erros seguem uma estrutura estável, segura e legível por máquinas?
  6. Coleções têm paginação, limites, filtros e ordenação determinística?
  7. Mudanças incompatíveis possuem política de versão e depreciação?
  8. Cache, ETag e precondições foram avaliados conforme o recurso?
  9. Autorização é verificada em cada objeto e ação?
  10. Limites de custo, tamanho, taxa e concorrência estão definidos?
  11. O contrato OpenAPI corresponde ao comportamento implantado?
  12. Testes negativos, métricas, logs e traces cobrem fluxos críticos?

Não é necessário implementar toda técnica na primeira versão. É necessário decidir conscientemente.

Uma API pequena pode começar com recursos claros, métodos corretos, erros padronizados, autorização e testes de contrato; cache avançado ou hipermídia entram quando resolvem problemas reais.

Perguntas frequentes

REST e HTTP são a mesma coisa?

Não. REST é um estilo arquitetural; HTTP é um protocolo com semântica de mensagens, métodos, cabeçalhos e status. REST não é limitado conceitualmente ao HTTP, mas a maioria das APIs REST usa HTTP porque seus mecanismos se encaixam na interface uniforme e no modelo de recursos.

Qual é a diferença entre PUT e PATCH?

PUT envia uma representação para criar ou substituir o estado do recurso na URL e é idempotente. PATCH envia instruções de modificação parcial; o comportamento e a idempotência dependem do formato usado. O contrato deve explicar campos ausentes, valores nulos e conflitos.

Uma API REST precisa usar JSON?

Não. JSON é popular por ser leve e amplamente suportado, mas REST trabalha com representações e tipos de mídia. Um recurso pode ser representado como JSON, XML, CSV, imagem ou outro formato negociado, desde que as mensagens sejam autodescritivas.

Conclusão

Uma API REST consistente nasce de decisões conectadas. Recursos e URLs definem a linguagem do domínio; métodos e status comunicam intenção e resultado; idempotência permite retentativas; erros, paginação e versionamento protegem clientes; cache, autorização, testes e observabilidade sustentam a operação.

Comece pelo contrato de um fluxo real. Modele os recursos, escreva exemplos de sucesso e falha, defina quem pode executar cada ação e teste o comportamento a partir do ponto de vista do consumidor.

Só depois escolha detalhes de framework. Assim, a tecnologia serve a uma interface previsível, em vez de ditar um conjunto de rotas acidentais.