Como integrar validação de CPF em Ionic com Angular e HTTP client

Aprenda a integrar validação de CPF em apps Ionic com Angular usando HttpClient, interceptors e a API da CPFHub.io.

Redação CPFHub.io
Redação CPFHub.io
··7 min de leitura
Como integrar validação de CPF em Ionic com Angular e HTTP client

Para integrar validação de CPF em um app Ionic com Angular, crie um serviço injetável que usa o HttpClient para chamar GET https://api.cpfhub.io/cpf/{CPF} com o header x-api-key. O Angular oferece interceptors que centralizam a autenticação automaticamente em todas as requisições, e os reactive forms garantem que o CPF seja validado no cliente antes mesmo de a chamada sair do dispositivo. A API da CPFHub.io responde em ~900ms e retorna nome, data de nascimento e gênero do titular — dados suficientes para a maioria dos fluxos de cadastro e verificação de identidade em apps mobile.


1. Pré-requisitos

  • Node.js 18+ e Ionic CLI: npm install -g @ionic/cli.

  • Um projeto Ionic/Angular criado: ionic start cpf-app blank --type=angular.

  • Uma conta gratuita na CPFHub.io

  • Consulte a documentação oficial do Ionic em ionicframework.com/docs para referência dos componentes usados neste guia.


2. Configure o environment

Adicione as configurações da API nos arquivos de environment do Angular:

// src/environments/environment.ts
export const environment = {
    production: false,
    cpfhub: {
    baseUrl: "https://api.cpfhub.io",
    apiKey: "SUA_CHAVE_DE_API",
    timeout: 5000,
    },
};
// src/environments/environment.prod.ts
export const environment = {
    production: true,
    cpfhub: {
    baseUrl: "https://api.cpfhub.io",
    apiKey: "${CPFHUB_API_KEY}",
    timeout: 5000,
    },
};

3. Crie as interfaces de tipagem

Defina interfaces TypeScript para modelar a resposta da API:

// src/app/models/cpf.model.ts
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 interface CpfError {
    message: string;
    statusCode: number;
}

4. Crie o serviço de consulta

Implemente o serviço Angular com HttpClient:

// src/app/services/cpfhub.service.ts
import { Injectable } from "@angular/core";
import { HttpClient, HttpHeaders, HttpErrorResponse } from "@angular/common/http";
import { Observable, throwError, timeout, catchError, map } from "rxjs";
import { environment } from "../../environments/environment";
import { CpfData, CpfResponse } from "../models/cpf.model";

@Injectable({
    providedIn: "root",
})
export class CpfHubService {
    private readonly baseUrl = environment.cpfhub.baseUrl;
    private readonly apiKey = environment.cpfhub.apiKey;
    private readonly timeoutMs = environment.cpfhub.timeout;

    constructor(private http: HttpClient) {}

    consultarCpf(cpf: string): Observable<CpfData> {
    const cpfLimpo = cpf.replace(/\D/g, "");

    if (cpfLimpo.length !== 11) {
    return throwError(() => ({
    message: "CPF deve conter exatamente 11 dígitos",
    statusCode: 400,
    }));
    }

    const url = `${this.baseUrl}/cpf/${cpfLimpo}`;
    const headers = new HttpHeaders({
    "x-api-key": this.apiKey,
    Accept: "application/json",
    });

    return this.http.get<CpfResponse>(url, { headers }).pipe(
    timeout(this.timeoutMs),
    map((response) => {
    if (response.success && response.data) {
    return response.data;
    }
    throw { message: "Resposta inesperada da API", statusCode: 500 };
    }),
    catchError((error) => this.handleError(error))
    );
    }

    private handleError(error: HttpErrorResponse | any): Observable<never> {
    if (error.name === "TimeoutError") {
    return throwError(() => ({
    message: "Timeout na consulta. Tente novamente.",
    statusCode: 504,
    }));
    }

    if (error instanceof HttpErrorResponse) {
    const errorMap: Record<number, string> = {
    400: "CPF com formato inválido",
    401: "Chave de API inválida ou ausente",
    404: "CPF não encontrado na base de dados",
    };

    return throwError(() => ({
    message: errorMap[error.status] || `Erro HTTP ${error.status}`,
    statusCode: error.status,
    }));
    }

    return throwError(() => ({
    message: error.message || "Erro desconhecido",
    statusCode: error.statusCode || 500,
    }));
    }
}

5. Crie o interceptor de autenticação

Use um interceptor para adicionar o header de API key automaticamente:

// src/app/interceptors/cpfhub.interceptor.ts
import { Injectable } from "@angular/core";
import {
    HttpInterceptor,
    HttpRequest,
    HttpHandler,
    HttpEvent,
} from "@angular/common/http";
import { Observable } from "rxjs";
import { environment } from "../../environments/environment";

@Injectable()
export class CpfHubInterceptor implements HttpInterceptor {
    intercept(
    req: HttpRequest<any>,
    next: HttpHandler
    ): Observable<HttpEvent<any>> {
    if (req.url.startsWith(environment.cpfhub.baseUrl)) {
    const cloned = req.clone({
    setHeaders: {
    "x-api-key": environment.cpfhub.apiKey,
    Accept: "application/json",
    },
    });
    return next.handle(cloned);
    }
    return next.handle(req);
    }
}

Registre o interceptor no módulo:

// src/app/app.module.ts
import { HTTP_INTERCEPTORS } from "@angular/common/http";
import { CpfHubInterceptor } from "./interceptors/cpfhub.interceptor";

@NgModule({
    providers: [
    {
    provide: HTTP_INTERCEPTORS,
    useClass: CpfHubInterceptor,
    multi: true,
    },
    ],
})
export class AppModule {}

6. Crie a página de consulta

Implemente a página Ionic com reactive forms:

// src/app/pages/consulta/consulta.page.ts
import { Component } from "@angular/core";
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { LoadingController, ToastController } from "@ionic/angular";
import { CpfHubService } from "../../services/cpfhub.service";
import { CpfData } from "../../models/cpf.model";

@Component({
    selector: "app-consulta",
    templateUrl: "./consulta.page.html",
    styleUrls: ["./consulta.page.scss"],
})
export class ConsultaPage {
    cpfForm: FormGroup;
    resultado: CpfData | null = null;
    erro: string | null = null;

    constructor(
    private fb: FormBuilder,
    private cpfService: CpfHubService,
    private loadingCtrl: LoadingController,
    private toastCtrl: ToastController
    ) {
    this.cpfForm = this.fb.group({
    cpf: ["", [Validators.required, Validators.minLength(11)]],
    });
    }

    async consultar(): Promise<void> {
    if (this.cpfForm.invalid) return;

    this.resultado = null;
    this.erro = null;

    const loading = await this.loadingCtrl.create({
    message: "Consultando CPF...",
    duration: 10000,
    });
    await loading.present();

    this.cpfService.consultarCpf(this.cpfForm.value.cpf).subscribe({
    next: async (data) => {
    this.resultado = data;
    await loading.dismiss();
    await this.mostrarToast("CPF encontrado com sucesso!", "success");
    },
    error: async (err) => {
    this.erro = err.message;
    await loading.dismiss();
    await this.mostrarToast(err.message, "danger");
    },
    });
    }

    private async mostrarToast(message: string, color: string): Promise<void> {
    const toast = await this.toastCtrl.create({
    message,
    duration: 3000,
    color,
    position: "bottom",
    });
    await toast.present();
    }

    formatarCpf(event: any): void {
    let value = event.target.value.replace(/\D/g, "").slice(0, 11);
    if (value.length > 9) {
    value = `${value.slice(0, 3)}.${value.slice(3, 6)}.${value.slice(6, 9)}-${value.slice(9)}`;
    } else if (value.length > 6) {
    value = `${value.slice(0, 3)}.${value.slice(3, 6)}.${value.slice(6)}`;
    } else if (value.length > 3) {
    value = `${value.slice(0, 3)}.${value.slice(3)}`;
    }
    this.cpfForm.patchValue({ cpf: value });
    }
}
<!-- src/app/pages/consulta/consulta.page.html -->
<ion-header>
    <ion-toolbar color="primary">
    <ion-title>Consulta de CPF</ion-title>
    </ion-toolbar>
</ion-header>

<ion-content class="ion-padding">
    <form [formGroup]="cpfForm" (ngSubmit)="consultar()">
    <ion-item>
    <ion-label position="floating">CPF</ion-label>
    <ion-input
    formControlName="cpf"
    type="text"
    placeholder="000.000.000-00"
    maxlength="14"
    (ionInput)="formatarCpf($event)"
    ></ion-input>
    </ion-item>

    <ion-button
    expand="block"
    type="submit"
    [disabled]="cpfForm.invalid"
    class="ion-margin-top"
    >
    Consultar
    </ion-button>
    </form>

    <ion-card *ngIf="resultado" class="ion-margin-top">
    <ion-card-header>
    <ion-card-title>{{ resultado.name }}</ion-card-title>
    <ion-card-subtitle>CPF: {{ resultado.cpf }}</ion-card-subtitle>
    </ion-card-header>
    <ion-card-content>
    <ion-list>
    <ion-item>
    <ion-label>Genero: {{ resultado.gender }}</ion-label>
    </ion-item>
    <ion-item>
    <ion-label>Nascimento: {{ resultado.birthDate }}</ion-label>
    </ion-item>
    </ion-list>
    </ion-card-content>
    </ion-card>

    <ion-card *ngIf="erro" color="danger" class="ion-margin-top">
    <ion-card-content>{{ erro }}</ion-card-content>
    </ion-card>
</ion-content>

7. Boas práticas

  • HttpClient -- Use o HttpClient do Angular com tipagem genérica para garantir type safety nas respostas da API.

  • Interceptors -- Centralize a adição de headers em interceptors para evitar repetição em cada chamada.

  • Timeout -- Configure timeout via operador RxJS timeout() para evitar que o app trave aguardando respostas. A latência típica da API é ~900ms; um timeout de 5 segundos é adequado.

  • Reactive Forms -- Use reactive forms com validadores para garantir que o CPF tenha o formato correto antes da consulta.

  • Ionic Components -- Aproveite componentes como LoadingController e ToastController para feedback visual nativo.

  • LGPD -- A API da CPFHub.io é 100% compatível com a LGPD. Em apps mobile, implemente controles de consentimento e política de privacidade.


Perguntas frequentes

Como funciona a autenticação na API da CPFHub.io em um app Ionic?

A autenticação usa o header HTTP x-api-key em cada requisição. No Angular, a prática recomendada é centralizar isso em um interceptor: o CpfHubInterceptor detecta requisições direcionadas ao domínio da API e injeta o header automaticamente, sem repetir código nos serviços. A chave de API é gerada no painel da CPFHub.io após o cadastro.

Qual o tempo de resposta esperado da API ao consultar um CPF?

A latência típica da API da CPFHub.io é de ~900ms. Configure o timeout do HttpClient para pelo menos 5 segundos para absorver variações de rede sem falsos erros. No Angular, use o operador timeout() do RxJS diretamente no pipe() do observable para controlar isso de forma reativa.

O que acontece quando o limite de consultas do plano gratuito é atingido?

A API não bloqueia a conta nem retorna erro 429 ao atingir o limite. O plano gratuito inclui 50 consultas por mês; ao superá-las, cada consulta adicional é cobrada a R$0,15, de forma automática. O plano Pro oferece 1.000 consultas por R$149/mês, com o mesmo modelo de cobrança por excedente.

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

Use o CPF apenas para a finalidade declarada ao titular, armazene apenas o estritamente necessário e implemente controle de acesso aos logs de consulta no app. A ANPD orienta que dados de identificação devem ser tratados com o princípio da necessidade — documente a base legal para o tratamento antes de colocar o app em produção.


Conclusão

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