Como Criar uma Camada de Abstração para Trocar de Provedor de API de CPF Facilmente

Aprenda a criar uma camada de abstração que permite trocar de provedor de API de CPF sem alterar o código da aplicação. Padrões Strategy e Adapter.

Redação CPFHub.io
Redação CPFHub.io
··6 min de leitura
Como Criar uma Camada de Abstração para Trocar de Provedor de API de CPF Facilmente

Introdução

Acoplar sua aplicação diretamente a um provedor de API de CPF é um risco técnico significativo. Se o provedor mudar sua interface, aumentar preços ou sair do mercado, você precisará alterar código em dezenas de pontos da aplicação. A solução é criar uma camada de abstração que isole sua lógica de negócio dos detalhes de implementação do provedor.

Por que abstrair o provedor de API

Sem abstração, cada chamada à API fica espalhada pelo código, criando um acoplamento forte que dificulta qualquer mudança futura.

CenárioSem abstraçãoCom abstração
Trocar de provedorAlterar N arquivosAlterar 1 adaptador
Adicionar cacheModificar cada chamadaAdicionar decorator
Testes unitáriosMock complexoInterface simples
Múltiplos provedoresCódigo duplicadoConfiguração
Mudança de contratoRefatoração massivaAjuste no adapter
  • Princípio da Inversão de Dependência -- módulos de alto nível não devem depender de módulos de baixo nível, ambos devem depender de abstrações
  • Princípio Aberto/Fechado -- o sistema deve ser aberto para extensão (novos provedores) e fechado para modificação
  • Testabilidade -- com uma interface definida, criar mocks para testes se torna trivial

Definindo a interface do contrato

O primeiro passo é definir um contrato que todos os provedores devem implementar. Isso garante que sua aplicação sempre receba dados no mesmo formato, independentemente da origem.

// contracts/cpf-provider.js
class CpfProviderInterface {
    /**
    * @param {string} cpf - CPF sem formatação
    * @returns {Promise<CpfResult>}
    */
    async consultar(cpf) {
    throw new Error("Método consultar() deve ser implementado");
    }
}

// Formato padronizado de resposta
class CpfResult {
    constructor({ cpf, nome, genero, dataNascimento, valido }) {
    this.cpf = cpf;
    this.nome = nome;
    this.genero = genero;
    this.dataNascimento = dataNascimento;
    this.valido = valido;
    }
}

module.exports = { CpfProviderInterface, CpfResult };
  • CpfResult -- objeto de valor que padroniza a resposta independentemente do provedor
  • CpfProviderInterface -- contrato que força cada adaptador a implementar o método consultar()
  • Desacoplamento -- sua aplicação conhece apenas CpfResult, nunca o formato raw da API

Implementando adaptadores por provedor

Cada provedor recebe seu próprio adaptador que traduz a resposta para o formato padronizado.

// adapters/cpfhub-adapter.js
const axios = require("axios");
const { CpfProviderInterface, CpfResult } = require("../contracts/cpf-provider");

class CpfHubAdapter extends CpfProviderInterface {
    constructor(apiKey) {
    super();
    this.apiKey = apiKey;
    this.baseUrl = "https://api.cpfhub.io";
    }

    async consultar(cpf) {
    const response = await axios.get(`${this.baseUrl}/cpf/${cpf}`, {
    headers: { "x-api-key": this.apiKey },
    timeout: 10000,
    });

    const { data } = response.data;
    return new CpfResult({
    cpf: data.cpf,
    nome: data.name,
    genero: data.gender,
    dataNascimento: data.birthDate,
    valido: response.data.success,
    });
    }
}

// adapters/provedor-alternativo-adapter.js
class ProvedorAlternativoAdapter extends CpfProviderInterface {
    constructor(token) {
    super();
    this.token = token;
    }

    async consultar(cpf) {
    const response = await axios.post("https://outro-provedor.com/api/v2/cpf", {
    documento: cpf,
    }, {
    headers: { Authorization: `Bearer ${this.token}` },
    });

    return new CpfResult({
    cpf: response.data.documento,
    nome: response.data.nome_completo,
    genero: response.data.sexo === "M" ? "male" : "female",
    dataNascimento: response.data.dt_nascimento,
    valido: response.data.status === "ativo",
    });
    }
}

module.exports = { CpfHubAdapter, ProvedorAlternativoAdapter };
  • Tradução de formato -- cada adapter mapeia os campos específicos do provedor para o formato padrão
  • Encapsulamento -- detalhes como headers de autenticação e URLs ficam isolados no adaptador
  • Extensibilidade -- adicionar um novo provedor significa apenas criar um novo adaptador

Criando a factory e o serviço

A factory cria o adaptador correto baseado na configuração, e o serviço expõe uma API limpa para o resto da aplicação.

// factory/cpf-provider-factory.js
const { CpfHubAdapter, ProvedorAlternativoAdapter } = require("../adapters");

function criarProvedor(config) {
    const provedores = {
    cpfhub: () => new CpfHubAdapter(config.CPFHUB_API_KEY),
    alternativo: () => new ProvedorAlternativoAdapter(config.ALT_TOKEN),
    };

    const factory = provedores[config.CPF_PROVIDER];
    if (!factory) {
    throw new Error(`Provedor desconhecido: ${config.CPF_PROVIDER}`);
    }
    return factory();
}

// services/cpf-service.js
class CpfService {
    constructor(provider) {
    this.provider = provider;
    }

    async validar(cpf) {
    const cpfLimpo = cpf.replace(/\D/g, "");
    if (cpfLimpo.length !== 11) {
    throw new Error("CPF deve conter 11 dígitos");
    }
    return this.provider.consultar(cpfLimpo);
    }
}

// Uso: trocar provedor é mudar uma variável de ambiente
const provider = criarProvedor(process.env);
const cpfService = new CpfService(provider);

// Em qualquer lugar da aplicação
const resultado = await cpfService.validar("123.456.789-09");
console.log(resultado.nome);
Padrão utilizadoBenefício
AdapterTraduz interfaces incompatíveis para um formato comum
FactoryCentraliza a criação de objetos baseada em configuração
StrategyPermite trocar algoritmos (provedores) em tempo de execução
Dependency InjectionO serviço recebe o provedor, não o cria internamente

Perguntas frequentes

O que é necessário para implementar validação de CPF neste contexto?

A validação de CPF exige uma chamada à API com o número do documento e a chave de autenticação. A CPFHub.io retorna o status do CPF, nome do titular e data de nascimento em menos de 200ms, permitindo a verificação em tempo real durante o cadastro ou transação.

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 integrar a API CPFHub.io?

A integração básica leva menos de 30 minutos: crie uma conta em cpfhub.io, gere a API key no painel e faça uma chamada GET para https://api.cpfhub.io/cpf/{CPF} com o header x-api-key. A documentação inclui exemplos em Python, Node.js, PHP, Java e outras linguagens.


Conclusão

Criar uma camada de abstração para sua API de CPF é um investimento que se paga rapidamente. Com adaptadores isolados, uma interface padronizada e uma factory configurável, trocar de provedor vira uma mudança de variável de ambiente. Comece implementando o padrão com a API da cpfhub.io.

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