Como integrar validação de CPF em aplicações Adonis.js (Node.js)

Aprenda a integrar a API de consulta de CPF da CPFHub.io em aplicações Adonis.js usando services, validators e controllers.

Redação CPFHub.io
Redação CPFHub.io
··7 min de leitura
Como integrar validação de CPF em aplicações Adonis.js (Node.js)

O Adonis.js é um framework Node.js completo, inspirado no Laravel, que oferece uma estrutura opinada com ORM, validação, autenticação e injeção de dependência embutidos. Para integrar a API de CPF da CPFHub.io, basta criar um service dedicado que faz um GET para https://api.cpfhub.io/cpf/{CPF} com o header x-api-key, usar o VineJS para validar a entrada e expor um controller com as rotas. A latência média é de ~900ms, então configure o AbortController com tempo suficiente — 5 a 10 segundos é adequado para produção.


1. Pré-requisitos

  • Adonis.js v6 configurado com npm init adonisjs@latest.

  • Node.js 20+ instalado.

  • Uma conta na CPFHub.io


2. Configure as variáveis de ambiente

Adicione as variáveis no arquivo .env:

CPFHUB_API_KEY=SUA_CHAVE_DE_API
CPFHUB_BASE_URL=https://api.cpfhub.io
CPFHUB_TIMEOUT=5000

Registre a validação no env.ts:

// start/env.ts
import { Env } from '@adonisjs/core/env'

export default await Env.create(new URL('../', import.meta.url), {
    // ... outras variáveis
    CPFHUB_API_KEY: Env.schema.string(),
    CPFHUB_BASE_URL: Env.schema.string({ format: 'url' }),
    CPFHUB_TIMEOUT: Env.schema.number(),
})

3. Crie o service de consulta

Crie o serviço em app/services/cpfhub_service.ts:

// app/services/cpfhub_service.ts
import env from '#start/env'

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

export interface CpfResponse {
    success: boolean
    data: CpfData
}

export default class CpfHubService {
    private baseUrl: string
    private apiKey: string
    private timeout: number

    constructor() {
    this.baseUrl = env.get('CPFHUB_BASE_URL')
    this.apiKey = env.get('CPFHUB_API_KEY')
    this.timeout = env.get('CPFHUB_TIMEOUT')
    }

    async consultarCpf(cpf: string): Promise<CpfResponse> {
    const cpfLimpo = cpf.replace(/\D/g, '')

    if (cpfLimpo.length !== 11) {
    throw new Error('CPF deve conter 11 dígitos')
    }

    const controller = new AbortController()
    const timeoutId = setTimeout(() => controller.abort(), this.timeout)

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

    clearTimeout(timeoutId)

    if (!response.ok) {
    const mensagens: Record<number, string> = {
    400: 'CPF com formato inválido',
    401: 'Chave de API inválida ou ausente',
    404: 'CPF não encontrado',
    }

    throw new Error(mensagens[response.status] || `Erro HTTP ${response.status}`)
    }

    return await response.json()
    } catch (error) {
    clearTimeout(timeoutId)
    throw error
    }
    }
}

4. Crie o validator

O Adonis.js tem um sistema de validação robusto. Crie um validator para o CPF:

// app/validators/cpf_validator.ts
import vine from '@vinejs/vine'

export const cpfValidator = vine.compile(
    vine.object({
    cpf: vine
    .string()
    .trim()
    .regex(/^\d{11}$/)
    .fixedLength(11),
    })
)

5. Crie o controller

// app/controllers/cpf_controller.ts
import type { HttpContext } from '@adonisjs/core/http'
import CpfHubService from '#services/cpfhub_service'
import { cpfValidator } from '#validators/cpf_validator'

export default class CpfController {
    private cpfHubService: CpfHubService

    constructor() {
    this.cpfHubService = new CpfHubService()
    }

    async show({ params, response }: HttpContext) {
    const cpf = params.cpf.replace(/\D/g, '')

    try {
    await cpfValidator.validate({ cpf })
    } catch {
    return response.badRequest({ error: 'CPF deve conter exatamente 11 dígitos numéricos' })
    }

    try {
    const resultado = await this.cpfHubService.consultarCpf(cpf)
    return response.ok(resultado)
    } catch (error) {
    if (error instanceof Error) {
    return response.badRequest({ error: error.message })
    }
    return response.internalServerError({ error: 'Erro interno' })
    }
    }

    async validate({ request, response }: HttpContext) {
    const payload = await request.validateUsing(cpfValidator)

    try {
    const resultado = await this.cpfHubService.consultarCpf(payload.cpf)

    if (resultado.success) {
    return response.ok({
    valid: true,
    name: resultado.data.name,
    birthDate: resultado.data.birthDate,
    gender: resultado.data.gender,
    })
    }

    return response.ok({ valid: false })
    } catch (error) {
    return response.badGateway({
    error: error instanceof Error ? error.message : 'Falha na validação',
    })
    }
    }
}

6. Registre as rotas

// start/routes.ts
import router from '@adonisjs/core/services/router'

const CpfController = () => import('#controllers/cpf_controller')

router.get('/api/cpf/:cpf', [CpfController, 'show'])
router.post('/api/cpf/validate', [CpfController, 'validate'])

7. Teste com cURL

Inicie o servidor e teste:

node ace serve --watch
curl -X GET http://localhost:3333/api/cpf/12345678900 \
    -H "Accept: application/json"

Resposta esperada:

{
    "success": true,
    "data": {
    "cpf": "12345678900",
    "name": "João da Silva",
    "nameUpper": "JOÃO DA SILVA",
    "gender": "M",
    "birthDate": "15/06/1990",
    "day": 15,
    "month": 6,
    "year": 1990
    }
}

8. Middleware de rate limiting

Crie um middleware para limitar consultas por IP:

// app/middleware/rate_limit_middleware.ts
import type { HttpContext } from '@adonisjs/core/http'
import type { NextFn } from '@adonisjs/core/types/http'

const requests = new Map<string, { count: number; timestamp: number }>()

export default class RateLimitMiddleware {
    async handle({ request, response }: HttpContext, next: NextFn) {
    const ip = request.ip()
    const now = Date.now()
    const windowMs = 60000 // 1 minuto
    const maxRequests = 30

    const entry = requests.get(ip)

    if (entry && now - entry.timestamp < windowMs) {
    if (entry.count >= maxRequests) {
    return response.tooManyRequests({
    error: 'Limite de requisições excedido. Tente novamente em 1 minuto.',
    })
    }
    entry.count++
    } else {
    requests.set(ip, { count: 1, timestamp: now })
    }

    return next()
    }
}

9. Boas práticas

  • Validação de env -- O Adonis.js valida variáveis de ambiente na inicialização. Se CPFHUB_API_KEY estiver ausente, a aplicação não sobe.

  • Timeout -- Configure o AbortController com pelo menos 5 segundos para acomodar a latência média de ~900ms da API com margem de segurança.

  • Validators -- Use o VineJS (validador nativo do Adonis) para validar dados de entrada antes de chamar a API.

  • Services -- Centralize a lógica de integração em services para facilitar testes e manutenção.

  • Planos -- O plano gratuito da CPFHub.io inclui 50 consultas/mês. Quando o limite é atingido, a API não bloqueia: cobra R$0,15 por consulta extra. Para produção, o plano Pro (R$149/mês) inclui 1.000 consultas.

A documentação oficial do Adonis.js cobre o sistema de providers, validators e serviços em detalhe.


Perguntas frequentes

Como integrar a API de CPF em um projeto Adonis.js existente?

Crie um service em app/services/cpfhub_service.ts com o método consultarCpf, registre as variáveis de ambiente no env.ts e injete o service no controller. O Adonis.js valida as variáveis de ambiente na inicialização, então a aplicação não sobe se CPFHUB_API_KEY estiver ausente — o que previne erros silenciosos em produção.

Qual timeout configurar para a API da CPFHub.io no Adonis.js?

A latência média da API é de ~900ms. Configure o AbortController com pelo menos 5.000ms (5 segundos) para ter margem adequada em condições de rede variável. Em ambientes com alta carga, considere 8 a 10 segundos para evitar cancelamentos prematuros que gerariam falsos negativos na validação.

A API retorna erro 429 quando o limite de consultas é atingido?

Não. A CPFHub.io não bloqueia requisições ao atingir o limite do plano. Quando o limite mensal é excedido, cada consulta adicional é cobrada automaticamente a R$0,15. Por isso, implementar um middleware de rate limiting na aplicação Adonis.js é uma boa prática para controlar o volume e evitar cobranças inesperadas.

Como testar o service de CPF no Adonis.js sem consumir consultas reais?

Use a injeção de dependência do Adonis.js para criar um mock do CpfHubService nos testes. O framework suporta substituição de bindings no container de IoC, o que permite simular respostas da API sem fazer chamadas reais — preservando as consultas do plano para o ambiente de produção.


Conclusão

O Adonis.js oferece uma estrutura organizada e produtiva para integrar a API da CPFHub.io

Cadastre-se em 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