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
Ligações
Contexto
Seção intitulada “Contexto”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→Responseem 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 emsrc/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)
Opções consideradas
Seção intitulada “Opções consideradas”1. Apenas server functions do TanStack Start
Seção intitulada “1. Apenas server functions do TanStack Start”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
2. Server routes do TanStack Start
Seção intitulada “2. Server routes do TanStack Start”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
3. Hono
Seção intitulada “3. Hono”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-openapidá-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)
4. Express / Fastify
Seção intitulada “4. Express / Fastify”Os clássicos do Node.
Prós
- Express: toda a gente o conhece; o Express 5 (npm
latestdesde 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/expressem 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
5. tRPC
Seção intitulada “5. tRPC”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
Decisão
Seção intitulada “Decisão”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.
Consequências
Seção intitulada “Consequências”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-openapitransforma 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.

