Como consumir API de CPF em Supabase Edge Functions com Deno

Aprenda a consumir uma API de consulta de CPF em Supabase Edge Functions usando Deno e TypeScript. Exemplos com Supabase client e deploy.

Redação CPFHub.io
Redação CPFHub.io
··8 min de leitura
Como consumir API de CPF em Supabase Edge Functions com Deno

Quem usa Supabase como backend pode integrar a API da CPFHub.io diretamente em uma Edge Function — sem servidor dedicado, com TypeScript nativo no Deno e a chave de API guardada em secrets. O deploy leva menos de cinco minutos e a função fica disponível globalmente com latência baixa, validando CPFs em tempo real a partir de qualquer client JavaScript que já use o Supabase SDK.

Introdução

O Supabase vem se consolidando como uma alternativa open-source ao Firebase, oferecendo banco de dados PostgreSQL, autenticação, storage e Edge Functions -- funções serverless executadas no Deno, o runtime moderno para TypeScript e JavaScript. Para desenvolvedores que já utilizam Supabase como backend, as Edge Functions representam a forma mais natural de adicionar lógica de servidor, incluindo a validação de CPF.


1. Pré-requisitos

  • Conta no Supabase -- Com um projeto ativo.

  • Supabase CLI -- Para criar e gerenciar Edge Functions.

  • Deno instalado -- Para desenvolvimento local (o Supabase CLI o gerencia automaticamente).

  • Conta na CPFHub.io -- Cadastre-se em CPFHub.io para obter sua chave de API gratuita e começar com 50 consultas mensais sem cartão de crédito.

Instalando o Supabase CLI

npm install -g supabase
supabase login

2. Criando a Edge Function

supabase functions new validar-cpf

Isso cria a estrutura:

supabase/
└── functions/
    └── validar-cpf/
    └── index.ts

3. Implementação da função

// supabase/functions/validar-cpf/index.ts

import { serve } from 'https://deno.land/std@0.177.0/http/server.ts';

const CPFHUB_BASE_URL = 'https://api.cpfhub.io/cpf';

interface CpfData {
    cpf: string;
    name: string;
    nameUpper: string;
    gender: string;
    birthDate: string;
    day: number;
    month: number;
    year: number;
}

interface CpfResponse {
    success: boolean;
    data: CpfData;
}

serve(async (req: Request) => {
    // CORS
    if (req.method === 'OPTIONS') {
    return new Response(null, {
    status: 204,
    headers: {
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'POST, GET',
    'Access-Control-Allow-Headers': 'Content-Type, Authorization',
    },
    });
    }

    const corsHeaders = {
    'Access-Control-Allow-Origin': '*',
    'Content-Type': 'application/json',
    };

    try {
    let cpf: string | null = null;

    // Aceitar CPF via query string ou body JSON
    const url = new URL(req.url);
    cpf = url.searchParams.get('cpf');

    if (!cpf && req.method === 'POST') {
    const body = await req.json();
    cpf = body.cpf;
    }

    if (!cpf || !/^\d{11}$/.test(cpf)) {
    return new Response(
    JSON.stringify({ error: 'CPF invalido. Informe 11 digitos.' }),
    { status: 400, headers: corsHeaders }
    );
    }

    // Recuperar chave de API dos secrets
    const apiKey = Deno.env.get('CPFHUB_API_KEY');

    if (!apiKey) {
    console.error('CPFHUB_API_KEY nao configurada.');
    return new Response(
    JSON.stringify({ error: 'Erro de configuracao.' }),
    { status: 500, headers: corsHeaders }
    );
    }

    // Consultar a API com timeout
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 30000);

    const response = await fetch(`${CPFHUB_BASE_URL}/${cpf}`, {
    method: 'GET',
    headers: {
    'x-api-key': apiKey,
    'Accept': 'application/json',
    },
    signal: controller.signal,
    });

    clearTimeout(timeoutId);

    const data: CpfResponse = await response.json();

    if (response.ok && data.success) {
    return new Response(
    JSON.stringify({ success: true, data: data.data }),
    { status: 200, headers: corsHeaders }
    );
    }

    return new Response(
    JSON.stringify({ error: 'CPF nao encontrado.' }),
    { status: 404, headers: corsHeaders }
    );
    } catch (error) {
    console.error('Erro:', error.message);

    if (error.name === 'AbortError') {
    return new Response(
    JSON.stringify({ error: 'Timeout na consulta.' }),
    { status: 504, headers: corsHeaders }
    );
    }

    return new Response(
    JSON.stringify({ error: 'Erro interno.' }),
    { status: 500, headers: corsHeaders }
    );
    }
});

4. Configurando Secrets

Adicione a chave de API como secret do Supabase:

supabase secrets set CPFHUB_API_KEY=SUA_CHAVE_DE_API

Para verificar os secrets configurados:

supabase secrets list

5. Integrando com o banco de dados Supabase

Para armazenar resultados de consultas no banco de dados (cache e auditoria):

// Trecho para adicionar ao index.ts

import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';

const supabaseUrl = Deno.env.get('SUPABASE_URL')!;
const supabaseKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!;
const supabase = createClient(supabaseUrl, supabaseKey);

async function salvarConsulta(cpfData: CpfData): Promise<void> {
    const { error } = await supabase
    .from('consultas_cpf')
    .upsert({
    cpf: cpfData.cpf,
    nome: cpfData.name,
    genero: cpfData.gender,
    data_nascimento: cpfData.birthDate,
    consultado_em: new Date().toISOString(),
    }, {
    onConflict: 'cpf',
    });

    if (error) {
    console.error('Erro ao salvar consulta:', error.message);
    }
}

async function buscarCache(cpf: string): Promise<CpfData | null> {
    const { data, error } = await supabase
    .from('consultas_cpf')
    .select('*')
    .eq('cpf', cpf)
    .gte('consultado_em', new Date(Date.now() - 86400000).toISOString())
    .single();

    if (error || !data) return null;

    return {
    cpf: data.cpf,
    name: data.nome,
    nameUpper: data.nome.toUpperCase(),
    gender: data.genero,
    birthDate: data.data_nascimento,
    day: 0,
    month: 0,
    year: 0,
    };
}

SQL para criar a tabela:

CREATE TABLE consultas_cpf (
    cpf TEXT PRIMARY KEY,
    nome TEXT NOT NULL,
    genero TEXT,
    data_nascimento TEXT,
    consultado_em TIMESTAMPTZ DEFAULT NOW()
);

6. Exemplo de resposta da API

A API da CPFHub.io retorna um JSON estruturado com todos os dados do titular:

{
    "success": true,
    "data": {
    "cpf": "12345678900",
    "name": "Joao da Silva",
    "nameUpper": "JOAO DA SILVA",
    "gender": "M",
    "birthDate": "15/06/1990",
    "day": 15,
    "month": 6,
    "year": 1990
    }
}
  • success -- Indica se a consulta foi bem-sucedida.
  • name / nameUpper -- Nome completo do titular.
  • gender -- Gênero (M ou F).
  • birthDate -- Data de nascimento completa.
  • day, month, year -- Componentes da data separados.

7. Testando e deploy

Teste local

supabase start
supabase functions serve validar-cpf --env-file .env.local

Teste com cURL:

curl -X GET "http://localhost:54321/functions/v1/validar-cpf?cpf=12345678900" \
    -H "Authorization: Bearer SEU_ANON_KEY" \
    --max-time 30

Deploy para produção

supabase functions deploy validar-cpf

8. Chamando a função pelo client JavaScript

import { createClient } from '@supabase/supabase-js';

const supabase = createClient('https://seu-projeto.supabase.co', 'SUA_ANON_KEY');

async function validarCpf(cpf) {
    const { data, error } = await supabase.functions.invoke('validar-cpf', {
    body: { cpf },
    });

    if (error) {
    console.error('Erro:', error.message);
    return null;
    }

    return data;
}

// Uso
const resultado = await validarCpf('12345678900');
console.log(resultado);

9. Boas práticas

  • Use secrets do Supabase -- Nunca exponha a chave de API no código ou em variáveis de ambiente do client.

  • Configure timeout -- O AbortController com 30 segundos evita que a função fique bloqueada.

  • Implemente cache no banco -- Armazene resultados de consultas no PostgreSQL do Supabase para reduzir chamadas à API.

  • Monitore no dashboard -- Acompanhe logs e métricas das Edge Functions pelo painel do Supabase.

  • Gerencie o consumo -- O plano gratuito da CPFHub.io oferece 50 consultas/mês sem cartão de crédito. O plano Pro (R$149/mês) inclui 1.000 consultas, e consultas extras custam R$0,15 cada — sem bloqueio.


Perguntas frequentes

O que é necessário para implementar validação de CPF em Supabase Edge Functions?

Você precisa de uma conta no Supabase com um projeto ativo, o Supabase CLI instalado e uma chave de API da CPFHub.io. Com esses três elementos, a Edge Function fica pronta em menos de 15 minutos — a chave vai para os secrets do Supabase e a função consulta https://api.cpfhub.io/cpf/{CPF} com o header x-api-key.

A API CPFHub.io funciona para todos os volumes de consulta?

Sim. O plano gratuito oferece 50 consultas por mês sem cartão de crédito — ideal para testes e projetos pequenos. Para volumes maiores, o plano Pro inclui 1.000 consultas mensais por R$149. Se o limite for ultrapassado, a API não bloqueia: cobra R$0,15 por consulta adicional.

Como garantir conformidade com a LGPD ao usar uma API de CPF?

Use o CPF apenas para a finalidade declarada ao titular, armazene apenas o necessário (não guarde o CPF cru se um token bastar), implemente controle de acesso aos logs de consulta e documente a base legal para o tratamento. A ANPD orienta que dados de identificação devem ser tratados com o princípio da necessidade.

Quanto tempo leva para fazer o deploy da Edge Function em produção?

Com o Supabase CLI configurado, o deploy leva menos de 2 minutos: supabase secrets set CPFHUB_API_KEY=SUA_CHAVE seguido de supabase functions deploy validar-cpf. A função fica disponível globalmente em segundos.


Conclusão

As Supabase Edge Functions com Deno oferecem uma plataforma moderna e integrada para validação de CPF. A combinação de TypeScript nativo, acesso direto ao banco de dados PostgreSQL e gerenciamento de secrets torna o Supabase uma excelente escolha para projetos que já utilizam a plataforma como backend.

A CPFHub.io complementa essa arquitetura com uma API simples, dados confiáveis e planos flexíveis que escalam sem bloquear requisições quando o volume aumenta.

Cadastre-se em cpfhub.io — 50 consultas mensais gratuitas, sem cartão de crédito — e comece hoje mesmo.

CPFHub.io

Pronto para integrar a API?

50 consultas gratuitas para testar agora. Sem cartão de crédito. Acesso imediato à documentação.

Redação CPFHub.io

Sobre a redação

Redação CPFHub.io

Time editorial especializado em APIs de CPF, identidade digital e compliance no mercado brasileiro. Produzimos guias técnicos, análises regulatórias e tutoriais sobre LGPD e KYC para desenvolvedores e líderes de produto.

WhatsAppFale conosco via WhatsApp