Este artigo estende duas comparações já publicadas neste blog: nossa análise da compatibilidade do PostgREST e suas alternativas e nossa comparação dedicada às camadas GraphQL no Postgres. Aqui o ângulo muda: uma grade de decisão entre três maneiras de construir uma camada de API, com Hasura tratado por suas permissões e pontos de extensão de negócios em vez de sua sintaxe GraphQL, e uma API escrita à mão como uma opção por si só, não uma simples linha “else” na parte inferior da tabela.
O essencial
- PostgREST gera automaticamente uma API REST a partir do esquema Postgres — nenhuma lógica de negócios arbitrária é possível, o RLS continua sendo o único limite de segurança.
- Hasura adiciona seu próprio sistema de permissões por função e tabela, ações para conectar um webhook de negócios, gatilhos de eventos e endpoints RESTificados em cima de seu mecanismo GraphQL.
- Uma API personalizada (Node.js, Express, Fastify...) oferece controle total sobre a lógica de negócios, validação e autenticação — ao custo de escrever, testar e manter tudo sozinho.
- No Aurabase, a camada PostgREST é uma instância real; a lógica de negócios além do CRUD passa por funções SQL expostas no RPC ou por Edge Functions, e não por meio de um servidor Node separado para hospedar.
- As três abordagens não são necessariamente mutuamente exclusivas: combinar PostgREST para CRUD e uma API personalizada para operações confidenciais é um padrão comum em produção.
A verdadeira escolha: quem escreve a lógica de negócios e onde
A questão “PostgREST ou Hasura ou API customizada” esconde uma questão mais útil: quem escreve sua lógica de negócio, com qual ferramenta e quem usa esse código na produção? As três arquiteturas respondem de maneira diferente, e essa diferença estrutura todo o resto – segurança, velocidade de implementação, dívida técnica no longo prazo.
| Origem da API | Gerado a partir do esquema SQL | Gerado a partir do esquema, por meio do mecanismo GraphQL Hasura | Rota escrita por rota, à mão |
|---|---|---|---|
| Lógica de negócios personalizada | Somente funções SQL (RPC) | Ações (webhook) + gatilhos de eventos | Qualquer código, sem restrições de ferramentas |
| Modelo de segurança | RLS Postgres, função orientada por JWT | Permissões específicas para função/tabela, não uma delegação para o RLS | O que você codifica (middleware, ORM, RLS opcional) |
| Para acomodar além | Nada — um binário leve | O motor Hasura, com base de metadados própria | O servidor de aplicativos completo |
| Curva de aprendizado | Baixo se a equipe já souber escrever SQL | Médio – um novo sistema de permissões e configuração | Nada na ferramenta, mas todo o resto para projetar |
| PÓS-GREST | HASURA | API PERSONALIZADA |
Nenhuma das três colunas é estritamente melhor: cada uma transfere o trabalho para outro lugar. PostgREST move-o para SQL, Hasura para configuração e webhooks, uma API personalizada para código de aplicativo clássico.
PostgREST: a API como reflexo direto do esquema
PostgREST transforma seu esquema Postgres em uma API REST — filtros, incorporação de relacionamento, RPC, RLS orientado por JWT — sem back-end para gravação. Detalhamos esse escopo em profundidade em nosso artigo sobre sua compatibilidade real com e suas alternativas; o que importa para esta comparação é onde o PostgREST para.
PostgREST não tem noção de lógica de negócios arbitrária. Cada regra deve ser expressa em SQL: uma função RPC, um gatilho, uma restrição, uma política RLS. Esta é uma restrição aceita, não um descuido — o diagrama continua sendo a única fonte de verdade, o que elimina qualquer desvio entre uma camada de aplicação e a base que ela serve.
Concretamente, é impossível ligar para um serviço de pagamento de terceiros, enviar um e-mail de confirmação ou calcular uma pontuação em JavaScript a partir de uma solicitação direta do PostgREST. Esta lógica deve residir no SQL (função pl/pgsql) ou ser acionada externamente - um gatilho que publica um evento NOTIFY, ouvido por um serviço externo que não é mais PostgREST.
Hasura: permissões declaradas, lógica de negócios enxertada por webhook
Nosso artigo sobre camadas GraphQL no Postgres detalha onde o mecanismo Hasura é executado e como suas permissões diferem do RLS do Postgres. Aqui, o ângulo é o da lógica de negócios: como inserir código personalizado em um banco de dados gerenciado pela Hasura e onde.
Uma ação Hasura expõe uma mutação ou consulta GraphQL personalizada, apoiada por um webhook HTTP que você escreve na linguagem de sua escolha. Hasura valida as entradas de acordo com o esquema declarado, chama seu webhook e retorna sua resposta ao cliente. É a porta de entrada para qualquer lógica que vá além do CRUD: chamada para um provedor de pagamento, cálculo complexo, orquestração em várias etapas.
Os Event Triggers seguem o sentido oposto: uma inserção, uma atualização ou uma exclusão em uma tabela aciona um webhook, de forma assíncrona e com reinicialização automática em caso de falha. Este é o mecanismo que a maioria das integrações Hasura usa para sincronizar um serviço de terceiros (faturamento, e-mail transacional, mecanismo de busca) sem acoplar esse código à solicitação inicial do cliente.
Hasura também pode expor uma consulta GraphQL já escrita como uma rota REST típica, com um caminho nomeado e parâmetros - seus endpoints RESTified, na terminologia de sua própria documentação. Útil se sua equipe de front-end preferir consumir REST, sem abrir mão do mecanismo de permissões GraphQL subjacente.
As permissões Hasura são um sistema específico do Hasura, por função e por tabela, não uma delegação ao RLS do Postgres. Dois locais para auditar regras de acesso em vez de apenas um — um custo real a ser comparado com a flexibilidade obtida com Ações e Acionadores de Eventos.
Lembrete de contexto, desenvolvido em nosso artigo dedicado: Hasura reorientou sua comunicação no PromptQL, uma camada projetada para agentes de IA, desde junho de 2025 — sem remover seu mecanismo GraphQL, ainda apresentado como “testado em batalha” em seu site oficial.
API personalizada (Node.js, Express, Fastify): codifique tudo, controle tudo
Uma API escrita à mão não tem, por definição, limites: qualquer lógica de negócios, em qualquer linguagem, com quaisquer dependências. É também a única das três opções onde nada é gerado para você – cada rota, cada validação, cada conexão com o banco de dados é um código que você possui e deve manter.
O que este modelo oferece, em troca de trabalho manual: controle total sobre erros e códigos HTTP retornados, testabilidade clássica (manipuladores, não configuração declarativa) e nenhuma nova DSL para aprender para uma equipe que já domina sua linguagem.
Quanto custa, em troca: CRUD, paginação e filtros para escrever e manter manualmente para cada recurso; autenticação e autorização para implementar e auditar você mesmo, sem RLS herdado automaticamente; o risco de consultas N+1 se cada relacionamento aninhado acionar sua própria consulta Postgres sem disciplina; e documentação da API a ser mantida manualmente ou por meio de um gerador de terceiros para integração.
Sobre desempenho bruto, a questão “O Node.js é mais lento que o Rust” é um tópico por si só - nosso artigo sobre Rust vs latência do Node.js cobre isso em detalhes, com metodologia declarada upstream em nossa página de metodologia de benchmark . Uma API personalizada tem o mesmo perfil de desempenho de qualquer serviço HTTP que você já usa, nem melhor nem pior por construção. Para saber exatamente onde o PostgREST satura e em que ponto uma camada customizada se torna necessária, veja nosso artigo sobre os reais limites do PostgREST em produção.
Tabela comparativa: as três opções lado a lado
Além da arquitetura, quatro critérios surgem com mais frequência na escolha: velocidade de implementação, flexibilidade real de negócios, dívida técnica de longo prazo e o caso de uso típico em que cada opção é mais confortável.
| Configuração inicial | Minutos — o esquema já existe | Horário — conecte a base, configure permissões | Dias a semanas – escreva cada rota |
|---|---|---|---|
| Flexibilidade de negócios | Limitado a SQL (RPC, gatilhos) | Bom por meio de gatilhos de ações/eventos, mas passa por um webhook externo | Total, direto |
| Dívida técnica a prazo | Fraco – o diagrama continua sendo a única fonte da verdade | Médio – metadados Hasura para manter além do esquema | Alta se a equipe cresce sem disciplina (testes, documentação, revisão) |
| Caso de uso típico | CRUD direto em um esquema estável, equipe confortável em SQL | Federar diversas fontes de dados ou lógica orientada a agente de IA | Lógica de negócios complexa, inúmeras integrações de terceiros |
| PÓS-GREST | HASURA | API PERSONALIZADA |
Para onde vai a lógica de negócios em um projeto Aurabase
Em um projeto de mecanismo Aurabase Postgres, a camada CRUD já é coberta por uma instância PostgREST real, não por uma reimplementação aproximada. A questão que fica em aberto para esta comparação: onde escrever o que vai além do CRUD?
Existem dois caminhos e não são mutuamente exclusivos. A primeira: uma função SQL exposta em RPC, para qualquer lógica que seja razoável expressar em SQL — cálculo de um total, validação cruzada entre várias tabelas, atualizações em cascata em uma única transação.
A segunda forma: Edge Functions, para tudo que vai além do domínio SQL — chamar uma API de pagamento, enviar um email, calcular uma incorporação. Dois caminhos levam até lá no Aurabase: o editor Studio, que executa código Deno (TypeScript) exatamente como no Supabase, e o aura functions deployCLI, que visa um caminho separado para funções escritas em Rust e compiladas em WASM - detalhadas em nossa arquitetura Rust unificada. Nenhum dos caminhos requer hospedagem de um servidor Node separado, ao contrário da opção pura de “API personalizada” neste artigo, onde esse servidor é inteiramente de sua responsabilidade.
Esta distribuição não é um compromisso instável entre os três modelos comparados aqui: é literalmente PostgREST para CRUD, um tijolo próximo de Hasura Actions para lógica de eventos via RPC e gatilhos, e Edge Functions que evitam a operação de um servidor de aplicação completo - sem nunca forçar uma escolha binária entre "todos PostgREST" e "todos personalizados".
Como escolher de acordo com seu contexto
Quatro situações surgem com mais frequência. A escolha certa depende principalmente do que sua lógica de negócios exige, e não da popularidade de uma ferramenta.
- Seu esquema é estável e sua lógica de negócios está em SQL. PostgREST auto-hospedado, ou integrado nativamente (Aurabase, Supabase), é suficiente: nada mais para hospedar, e o esquema continua sendo a única fonte de verdade.
- Você deseja reunir várias fontes de dados ou seu roteiro é voltado para agentes de IA que consomem seus dados. Hasura, com sua camada PromptQL, se adapta melhor a esse terreno.
- Seu produto possui uma lógica de negócios rica, inúmeras integrações de terceiros e uma equipe já equipada com uma linguagem de aplicação. Uma API personalizada continua sendo a escolha mais direta, ao custo de escrevê-la e mantê-la ao longo do tempo.
- Você deseja CRUD autogerado sem abrir mão de espaço real para lógica de negócios (RPC, Edge Functions), sem empilhar mais um serviço de aplicativo para explorar. Este é o ângulo documentado nesta comparação aplicada ao Aurabase, seção anterior.