Adios
BlogGuia

Guia

Como projetar uma API pequena para produção

Um projeto inicial para produção não precisa de dezenas de abstrações. Precisa de um escopo de processo claro, configuração previsível e sinais suficientes para uma operação segura.

Equipe AdiosAtualizado 17 de julho de 20268 min de leitura

A primeira versão de produção deve ser pequena o suficiente para entender sob pressão.

Tornar a inicialização determinística

Um serviço deve iniciar com um único comando documentado, escutar na porta configurada e retornar um erro útil quando faltar uma configuração obrigatória. Evite configurações que dependam de arquivos ou do estado do shell fora do repositório e do manifesto.

Execute migrações de esquema como uma etapa explícita da publicação da versão quando o framework permitir. Ocultar uma migração destrutiva na inicialização torna cada réplica responsável por coordenar uma alteração no banco ao mesmo tempo.

name: orders-api
build_cmd: npm ci && npm run build
start_cmd: node dist/server.js

runtime:
  name: node@24
  port: 8080
  health_path: /healthz

Manter o caminho da solicitação visível

Comece com uma camada de rotas simples, código de domínio testável sem HTTP e um pequeno adaptador para cada dependência externa. Adicione fila, cache ou outro serviço somente quando a carga de trabalho justificar.

Retorne erros com estrutura consistente e identificadores de requisição. Propague o identificador pelos logs e pelas chamadas externas para acompanhar uma requisição com falha sem depender apenas do horário.

  • —Camada de rotas: interpretar a entrada HTTP e converter erros de domínio em respostas estáveis.
  • —Função de domínio: aplicar as regras dos pedidos sem depender do framework web.
  • —Adaptador de repositório: controlar o SQL e os limites das transações.
  • —Adaptador do provedor: aplique timeouts e traduza falhas externas.

Publicar com sinais para operação

No mínimo, exponha a prontidão, produza logs estruturados e trate o desligamento com tempo suficiente para concluir ou rejeitar corretamente as requisições em andamento. Defina limites de tempo para chamadas externas e limites de recursos que revelem vazamentos antes que afetem cargas de trabalho vizinhas.

Essas escolhas são simples, mas criam um serviço que a equipe consegue depurar. Acrescente arquitetura quando a aplicação precisar, não porque havia espaço para mais uma pasta no projeto inicial.

const close = async (signal) => {
  app.log.info({ signal }, "shutdown started");
  await app.close();
  await database.end();
  process.exit(0);
};

process.once("SIGTERM", () => close("SIGTERM"));
process.once("SIGINT", () => close("SIGINT"));

Testar uma falha completa

Antes de considerar o serviço pronto para produção, escolha uma dependência e provoque sua falha. Na API de pedidos, pare o PostgreSQL enquanto envia requisições. Novos pedidos devem falhar com uma resposta 503 dentro de um prazo definido, a prontidão deve retirar a réplica da rotação e os logs devem preservar o ID da requisição sem imprimir a string de conexão.

Restaure o PostgreSQL e confirme que o serviço volta a ficar pronto sem duplicar pedidos. Esse único exercício testa mais do contrato operacional real do que muitos testes unitários limitados às rotas.

Todos os artigos