icardb
Supabase na Prática: PostgreSQL com APIs Instantâneas
Voltar para artigosPROGRAMAÇÃO

Supabase na Prática: PostgreSQL com APIs Instantâneas

Por Equipe Editorial Icardb 7 min de leitura

Supabase posiciona-se como alternativa open-source ao Firebase, mas com uma diferença fundamental: usa PostgreSQL como base. Isso significa que você obtém a conveniência de APIs geradas automaticamente sem abrir mão de um banco relacional maduro, extensível e com décadas de investimento em performance e confiabilidade.

O Que É o Supabase

Supabase é uma plataforma de backend-as-a-service construída sobre PostgreSQL. Oferece autenticação com múltiplos provedores, APIs REST e GraphQL geradas automaticamente a partir do esquema do banco, realtime subscriptions via WebSocket, armazenamento de arquivos, edge functions e um dashboard administrativo completo. Todo o código é open-source e pode ser self-hosted.

A arquitetura central é PostgreSQL + PostgREST. PostgREST converte consultas HTTP em SQL, respeitando permissões definidas via PostgreSQL Row Level Security. Isso elimina a necessidade de escrever controllers repetitivos para CRUD simples, mantendo a lógica de segurança no banco onde pertence.

Supabase não é apenas para prototipação. Empresas como Mozilla, OpenAI e Amazon usam Supabase em produção. A plataforma escala horizontalmente via read replicas e connection pooling com PgBouncer.

Configuração Inicial e Estrutura de Projeto

Criar um projeto leva menos de um minuto. No dashboard web, você define a região (escolha a mais próxima dos usuários), a senha do banco e o nome do projeto. Supabase provisiona instância PostgreSQL, instância de autenticação GoTrue, e serviços complementares automaticamente.

bash
# Instalação do cliente JavaScript
npm install @supabase/supabase-js

# Variáveis de ambiente (.env.local)
VITE_SUPABASE_URL=https://<project>.supabase.co
VITE_SUPABASE_ANON_KEY=<chave-anonima-publica>

O cliente JavaScript conecta-se às APIs do projeto. Existem duas chaves: anon (pública) e service_role (secreta, bypassa RLS). A chave anon é segura para incluir no frontend porque o acesso real é controlado por RLS, não pela chave em si.

Row Level Security (RLS): Segurança no Banco

RLS é o mecanismo mais importante do Supabase. Sem ele, qualquer pessoa com a chave anon pode ler e escrever qualquer tabela. Com RLS habilitado, cada linha é filtrada por políticas PostgreSQL baseadas na identidade do usuário autenticado.

sql
-- Habilita RLS na tabela
ALTER TABLE public.posts ENABLE ROW LEVEL SECURITY;

-- Política: usuários veem apenas seus próprios posts
CREATE POLICY "Users can view own posts"
ON public.posts
FOR SELECT
TO authenticated
USING (auth.uid() = user_id);

-- Política: usuários podem inserir apenas como si mesmos
CREATE POLICY "Users can insert own posts"
ON public.posts
FOR INSERT
TO authenticated
WITH CHECK (auth.uid() = user_id);

Políticas podem ser complexas: verificar membresia em equipes, validar quotas de uso, ou restringir acesso a campos específicos. A vantagem é que a lógica de segurança vive no banco, sendo aplicada independentemente de qual cliente acessa: web app, mobile app, ou ferramenta administrativa.

Autenticação e Autorização

Supabase Auth suporta e-mail/senha, magic links, OAuth (Google, GitHub, Apple, etc.), SSO SAML e phone OTP. O fluxo de sessão usa JWTs com refresh tokens automáticos. No PostgreSQL, a função auth.uid() retorna o UUID do usuário autenticado, permitindo que políticas RLS identifiquem quem está solicitando.

typescript
import { createClient } from "@supabase/supabase-js";

const supabase = createClient(
  import.meta.env.VITE_SUPABASE_URL,
  import.meta.env.VITE_SUPABASE_ANON_KEY
);

// Login com e-mail e senha
const { data, error } = await supabase.auth.signInWithPassword({
  email: "usuario@exemplo.com",
  password: "senha-segura",
});

// Ouvinte de mudanças de estado de autenticação
supabase.auth.onAuthStateChange((event, session) => {
  console.log(event, session?.user?.id);
});

Para autorização baseada em papéis (roles), crie uma tabela user_roles e uma função has_role SECURITY DEFINER. Isso evita recursão em RLS e permite políticas como "apenas admins podem deletar".

APIs Geradas Automaticamente

PostgREST gera endpoints REST para todas as tabelas com RLS. Operações básicas de CRUD não requerem código backend. Filtros, ordenação, paginação e joins são suportados via query parameters.

typescript
// SELECT com filtros e ordenação
const { data: posts } = await supabase
  .from("posts")
  .select("id, title, created_at, profiles(name)")
  .eq("published", true)
  .order("created_at", { ascending: false })
  .range(0, 9); // paginação: primeiros 10

// INSERT
const { data, error } = await supabase
  .from("posts")
  .insert({ title: "Novo post", user_id: userId })
  .select()
  .single();

// UPSERT
await supabase
  .from("profiles")
  .upsert({ id: userId, username: "novo_nome" });

Para consultas complexas que excedem as capacidades do PostgREST, use Database Functions (stored procedures PostgreSQL) expostas via RPC. Isso mantém a lógica complexa no banco e evita múltiplas round-trips.

Realtime: Dados em Tempo Real

Supabase Realtime escuta o WAL (Write-Ahead Log) do PostgreSQL e transmite mudanças via WebSocket. Isso permite atualizações instantâneas em aplicações colaborativas: chats, notificações, dashboards ao vivo, e jogos multiplayer.

typescript
const channel = supabase
  .channel("posts-changes")
  .on(
    "postgres_changes",
    { event: "INSERT", schema: "public", table: "posts" },
    (payload) => {
      console.log("Novo post:", payload.new);
    }
  )
  .subscribe();

// Cleanup ao desmontar componente
channel.unsubscribe();

Realtime respeita RLS: o cliente só recebe mudanças em linhas que teria permissão para ler via SELECT. Isso evita vazamento de dados sensíveis mesmo em canais compartilhados.

Storage para Arquivos

Supabase Storage armazena arquivos em buckets S3-like com controle de acesso via RLS. Upload direto do navegador é seguro graças a signed URLs e políticas de bucket. Transformações de imagem (resize, format conversion) são suportadas via query parameters na URL.

typescript
// Upload com política RLS no bucket
const { data, error } = await supabase.storage
  .from("avatars")
  .upload(`public/${userId}.png`, file, {
    upsert: true,
    contentType: "image/png",
  });

// URL pública com transformação
const { data } = supabase.storage
  .from("avatars")
  .getPublicUrl(`public/${userId}.png`, {
    transform: { width: 200, height: 200, resize: "cover" },
  });

Edge Functions e Serverless

Edge Functions no Supabase usam Deno e rodam globalmente em regiões próximas aos usuários. São ideais para webhooks, processamento de pagamentos, integrações com APIs externas e lógica que não pode viver no cliente por segurança. Cada função é uma rota HTTP isolada escrita em TypeScript.

Para aplicações mais complexas, considere que Edge Functions têm cold starts e limites de execução. Lógica pesada de processamento ou jobs de longa duração são melhor servidos por workers dedicados ou filas de background (ex.: Inngest, BullMQ) conectados ao mesmo PostgreSQL.

Boas Práticas para Produção

  • Habilite RLS em TODAS as tabelas do schema public antes do primeiro deploy. Sem exceções.
  • Nunca exponha a service_role key no frontend. Use-a apenas em servidores confiáveis.
  • Use connection pooling: Supabase já inclui PgBouncer, mas configure corretamente no cliente.
  • Migrações via CLI: use supabase db push para versionar schema junto com código da aplicação.
  • Monitore quotas: projeto free tem limites de bandwidth, storage e conexões. Configure alertas.
  • Backup automático: habilite Point-in-Time Recovery (PITR) para projetos em produção.
  • Teste RLS: escreva testes automatizados que verificam se políticas permitem e bloqueiam corretamente.

Conclusão

Supabase democratiza o backend ao combinar PostgreSQL — o banco relacional mais confiável do mercado — com APIs instantâneas, autenticação pronta e realtime. Para desenvolvedores fullstack, elimina horas de boilerplate. Para equipes, centraliza segurança em RLS, reduzindo superfície de ataque.

A plataforma não é perfeita: consultas muito complexas ainda exigem functions, cold starts de edge functions existem, e o ecossistema é menor que AWS ou GCP. Mas para a maioria das aplicações web e mobile, Supabase oferece o melhor custo-benefício em velocidade de desenvolvimento, controle de dados e escalabilidade.

Perguntas frequentes

+Supabase é gratuito para produção?

O tier gratuito é generoso para prototipação e projetos pequenos, com limites de 500 MB de banco e 1 GB de storage. Para produção com tráfego real, o tier Pro ($25/mês) remove limites de bandwidth e adiciona suporte. Empresas usam tiers superiores.

+Posso sair do Supabase depois?

Sim. Como é open-source e usa PostgreSQL padrão, você pode fazer dump do banco e restaurar em qualquer provedor PostgreSQL. O vendor lock-in é mínimo comparado a plataformas proprietárias.

+RLS afeta performance?

Políticas simples têm overhead negligenciável. Políticas complexas com subconsultas podem impactar performance. Use EXPLAIN ANALYZE para auditar queries lentas e crie índices apropriados nas colunas usadas em políticas.

+Supabase substitui um backend Node.js/Django?

Para CRUD simples e autenticação, sim. Para lógica de negócio complexa, integrações com múltiplos sistemas, ou processamento assíncrono, você provavelmente ainda precisa de um backend dedicado. Muitos usam Supabase como camada de dados + auth e um backend separado para lógica de domínio.

+Como funciona o realtime com muitos usuários simultâneos?

Realtime escala via conexões WebSocket gerenciadas. O tier Pro suporta milhares de conexões simultâneas. Para escala massiva (dezenas de milhares), considere arquiteturas híbridas com Redis Pub/Sub ou filas de eventos.

Fontes consultadas

Revisão editorial: publicado em . Última revisão em . Conteúdo educativo, sem patrocínio das ferramentas citadas.

Crédito da imagem: Foto: Icardb / Gerado por IA (Uso Editorial)

Leia também