Pular para o conteúdo

ADR-0004 Camada de API

Camada de API HTTP padrão da empresa — Hono, montada em /api dentro da app TanStack Start.

Decisão
Hono em /api/*Construir a app
Estado
SubstituídaSubstituída por ADR-0036
Data
Âmbito
Predefinição da empresa para todas as novas apps

O TanStack Start (ADR-0002) traz três primitivas de servidor:

  • Server functions — chamadas RPC tipadas da nossa UI para o servidor. Excelentes para o fluxo de dados interno da UI, mas não são uma API HTTP pública: sem contrato REST, sem solução para clientes que não sejam React (apps móveis, integrações de parceiros, webhooks, scripts).
  • Server routes — handlers Request → Response em bruto nas rotas baseadas em ficheiros (server.handlers). Endpoints HTTP reais, mas sem definições de rotas validadas por schema e sem OpenAPI.
  • Middleware — createMiddleware, mais o middleware global de pedidos em src/start.ts, que corre por igual para SSR, server routes e server functions.

O que falta ao Start é um conjunto de ferramentas orientado para APIs. Precisamos de uma camada de API que:

  • exponha uma API HTTP standard e versionável em /api/*
  • tenha um ecossistema maduro de middleware HTTP (CORS, autenticação, secure headers, logging) para a superfície da API — a autenticação (ADR-0009) liga-se aqui; a limitação de pedidos corre uma camada antes, no middleware global de pedidos do Start (ADR-0010)
  • corra dentro do mesmo contentor Docker da app (ADR-0003) — sem um serviço separado para operar
  • se integre com a nossa biblioteca de validação, o Zod (ADR-0005)

Usar as server functions incluídas para tudo, sem um framework de API separado.

Prós

  • Zero dependências novas; tipado de ponta a ponta
  • Um único modelo mental para o código de servidor

Contras

  • Com forma de RPC, não de REST — sem contrato HTTP standard para clientes externos
  • Sem geração de OpenAPI; sem clientes gerados automaticamente para consumidores que não usem TS
  • Webhooks e integrações de terceiros tornam-se desajeitados

Handlers HTTP simples nas rotas de ficheiros do Start, partilhando o middleware do Start.

Prós

  • Zero dependências novas; os endpoints ficam junto das rotas que servem
  • A mesma cadeia de middleware do SSR e das server functions

Contras

  • Sem definições de rotas validadas por schema nem geração de OpenAPI — os contratos para clientes externos são mantidos à mão
  • Ecossistema de middleware HTTP pequeno em comparação com o do Hono
  • Acoplado ao Start — sem caminho para extrair a API para um serviço autónomo

Framework web leve e baseado em standards da web (APIs Request/Response), minúsculo, corre em qualquer runtime — Node, Bun, edge. Monta-se diretamente dentro do handler de servidor do TanStack Start.

Prós

  • API fetch standard da web — sem abstrações proprietárias, o código é portável
  • Ecossistema de middleware de primeira classe: CORS, autenticação, logging, limitação de pedidos, @hono/zod-validator
  • Monta-se em /api/* dentro do servidor TanStack Start — um contentor, um deploy
  • O @hono/zod-openapi dá-nos specs OpenAPI e clientes gerados quando precisarmos
  • Extrai-se limpamente para um serviço autónomo mais tarde, se um produto alguma vez ultrapassar o monólito
  • Minúsculo (~14 kB), rápido, ativamente mantido

Contras

  • Uma segunda forma de fazer trabalho de servidor — exige uma convenção escrita (ver Decisão) para que as server functions e as rotas Hono não se misturem
  • Comunidade mais pequena do que a do Express (embora a crescer depressa)

Os clássicos do Node.

Prós

  • Express: toda a gente o conhece; o Express 5 (npm latest desde 2025-03) finalmente trata erros assíncronos. Fastify: rápido, validado por schema, sistema de plugins maduro

Contras

  • Express: API de middleware datada, tipos via @types/express em vez de inferência, só Node
  • Fastify: sólido, mas só Node e anterior ao Request/Response standard da web — o Hono dá a mesma classe de desempenho com melhor portabilidade e inferência de TS
  • Nenhum dos dois se monta de forma tão natural no handler de servidor do TanStack Start

Camada de RPC tipada.

Prós

  • Excelente DX de TS para APIs internas

Contras

  • Sobrepõe-se quase por completo às server functions que já temos
  • Não é um contrato REST — má opção para clientes externos, webhooks, OpenAPI

O Hono é a camada de API padrão da empresa, montado em /api/* dentro do servidor TanStack Start (mesmo contentor Docker).

Convenção — dois padrões de servidor, uma regra:

  • Server functions → carregamento de dados e mutações internas da UI, consumidas apenas pela nossa própria app React
  • Rotas Hono (/api/*) → tudo o que seja consumido como API HTTP: clientes externos, webhooks, apps móveis, parceiros, e tudo o que precise do pipeline de middleware

Os fatores decisivos face às server routes do próprio Start: APIs standard da web, o ecossistema de middleware HTTP (a autenticação aterra aqui, ADR-0009), integração com o Zod via @hono/zod-validator, potencial de OpenAPI via @hono/zod-openapi, e um caminho de extração limpo para um serviço autónomo sem reescrever.

Mais fácil — o que isto desbloqueia para ADRs futuros:

  • Limitação de pedidos: aplicada antes do Hono, no middleware global de pedidos do Start, pelo que um único limitador cobre /api/*, as server functions e o SSR (ADR-0010)
  • Autenticação: o middleware do Hono protege as rotas da API independentemente do fluxo de sessão da UI
  • OpenAPI: o @hono/zod-openapi transforma os nossos schemas Zod numa spec e em clientes gerados
  • Observabilidade: um único ponto de middleware para logging/métricas de pedidos na superfície da API

Mais difícil — o que passamos a ter a cargo:

  • Dois padrões de servidor em cada app (server functions + rotas Hono). A convenção acima tem de ser seguida; a revisão de código encarrega-se de a fazer cumprir
  • O versionamento da API (/api/v1/...) é uma disciplina nossa, não uma funcionalidade do framework

Do que abdicamos: da simplicidade de padrão único do “só server functions” e da pureza RPC ao estilo tRPC na API externa. Aceite — um contrato HTTP standard para o mundo exterior vale um framework extra.