# Como consumir API de CPF em NestJS com módulos e providers

> Aprenda a consumir a API de consulta de CPF da CPFHub.io em NestJS usando módulos, providers, DTOs e o HttpModule com boas práticas.

**Publicado:** 31/05/2026
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/como-consumir-api-de-cpf-em-nestjs-com-modulos-e-providers

---

O **NestJS** é o framework Node.js mais adotado para aplicações empresariais, com arquitetura modular inspirada no Angular. Para consumir a API de CPF da CPFHub.io, crie um módulo dedicado com `HttpModule`, um service injetável que faz GET para `https://api.cpfhub.io/cpf/{CPF}` com o header `x-api-key`, e um controller com DTOs validados pelo `class-validator`. A latência média da API é de ~900ms — configure o timeout do Axios com margem suficiente para evitar falsos timeouts.

---

## 1. Pré-requisitos

* **NestJS** configurado com `nest new cpf-validator`.

* Node.js 18+ instalado.

* Pacotes adicionais: `@nestjs/axios`, `@nestjs/config`, `axios`, `class-validator`, `class-transformer`.

* Uma conta na [**CPFHub.io**](https://www.cpfhub.io/)

---

## 2. Instale as dependências

```bash
npm install @nestjs/axios @nestjs/config axios class-validator class-transformer
```

---

## 3. Configure as variáveis de ambiente

Crie o arquivo `.env`:

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

Registre o `ConfigModule` no `AppModule`:

```typescript
// src/app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { CpfModule } from './cpf/cpf.module';

@Module({
 imports: [
 ConfigModule.forRoot({ isGlobal: true }),
 CpfModule,
 ],
})
export class AppModule {}
```

---

## 4. Crie o módulo de CPF

```typescript
// src/cpf/cpf.module.ts
import { Module } from '@nestjs/common';
import { HttpModule } from '@nestjs/axios';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { CpfService } from './cpf.service';
import { CpfController } from './cpf.controller';

@Module({
 imports: [
 HttpModule.registerAsync({
 imports: [ConfigModule],
 inject: [ConfigService],
 useFactory: (config: ConfigService) => ({
 baseURL: config.get('CPFHUB_BASE_URL'),
 timeout: config.get<number>('CPFHUB_TIMEOUT', 5000),
 headers: {
 'x-api-key': config.get('CPFHUB_API_KEY'),
 'Accept': 'application/json',
 },
 }),
 }),
 ],
 controllers: [CpfController],
 providers: [CpfService],
 exports: [CpfService],
})
export class CpfModule {}
```

O `HttpModule.registerAsync` configura o Axios com a URL base, timeout e headers a partir das variáveis de ambiente.

---

## 5. Crie os DTOs

```typescript
// src/cpf/dto/cpf-response.dto.ts
export class CpfDataDto {
 cpf: string;
 name: string;
 nameUpper: string;
 gender: string;
 birthDate: string;
 day: number;
 month: number;
 year: number;
}

export class CpfResponseDto {
 success: boolean;
 data: CpfDataDto;
}
```

```typescript
// src/cpf/dto/cpf-param.dto.ts
import { IsString, Matches, Length } from 'class-validator';

export class CpfParamDto {
 @IsString()
 @Length(11, 11, { message: 'CPF deve conter exatamente 11 dígitos' })
 @Matches(/^\d{11}$/, { message: 'CPF deve conter apenas números' })
 cpf: string;
}
```

---

## 6. Crie o service

```typescript
// src/cpf/cpf.service.ts
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';
import { CpfResponseDto } from './dto/cpf-response.dto';

@Injectable()
export class CpfService {
 constructor(private readonly httpService: HttpService) {}

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

 try {
 const { data } = await firstValueFrom(
 this.httpService.get<CpfResponseDto>(`/cpf/${cpfLimpo}`),
 );

 return data;
 } catch (error) {
 if (error.response) {
 const status = error.response.status;
 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 HttpException(
 mensagens[status] || `Erro na API: HTTP ${status}`,
 status,
 );
 }

 if (error.code === 'ECONNABORTED') {
 throw new HttpException(
 'Timeout na consulta de CPF',
 HttpStatus.GATEWAY_TIMEOUT,
 );
 }

 throw new HttpException(
 'Falha na conexão com a API de CPF',
 HttpStatus.BAD_GATEWAY,
 );
 }
 }
}
```

---

## 7. Crie o controller

```typescript
// src/cpf/cpf.controller.ts
import { Controller, Get, Param, UsePipes, ValidationPipe } from '@nestjs/common';
import { CpfService } from './cpf.service';
import { CpfParamDto } from './dto/cpf-param.dto';

@Controller('api/cpf')
export class CpfController {
 constructor(private readonly cpfService: CpfService) {}

 @Get(':cpf')
 @UsePipes(new ValidationPipe({ transform: true }))
 async consultar(@Param() params: CpfParamDto) {
 return this.cpfService.consultarCpf(params.cpf);
 }
}
```

---

## 8. Teste com cURL

Inicie a aplicação e teste:

```bash
npm run start:dev
```

```bash
curl -X GET http://localhost:3000/api/cpf/12345678900 \
 -H "Accept: application/json"
```

Resposta esperada:

```json
{
 "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
 }
}
```

---

## 9. Testes unitários

Teste o service com mock do HttpService:

```typescript
// src/cpf/cpf.service.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { HttpService } from '@nestjs/axios';
import { of } from 'rxjs';
import { CpfService } from './cpf.service';

describe('CpfService', () => {
 let service: CpfService;
 let httpService: HttpService;

 beforeEach(async () => {
 const module: TestingModule = await Test.createTestingModule({
 providers: [
 CpfService,
 {
 provide: HttpService,
 useValue: {
 get: jest.fn(),
 },
 },
 ],
 }).compile();

 service = module.get<CpfService>(CpfService);
 httpService = module.get<HttpService>(HttpService);
 });

 it('deve retornar dados do CPF', async () => {
 const mockResponse = {
 data: {
 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,
 },
 },
 };

 jest.spyOn(httpService, 'get').mockReturnValue(of(mockResponse) as any);

 const result = await service.consultarCpf('12345678900');
 expect(result.success).toBe(true);
 expect(result.data.name).toBe('João da Silva');
 });
});
```

---

## 10. Boas práticas

* **Módulos** -- Encapsule a integração com a CPFHub.io em um módulo dedicado que pode ser reutilizado em toda a aplicação.

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

* **DTOs e ValidationPipe** -- Valide os parâmetros de entrada com `class-validator` antes de chamar a API.

* **Injeção de dependência** -- O padrão DI do NestJS facilita testes unitários com mocks do HttpService.

* **ConfigService** -- Centralize variáveis de ambiente no `ConfigModule`. Nunca hardcode chaves no código.

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

A [documentação oficial do NestJS](https://docs.nestjs.com/techniques/http-module) detalha o `HttpModule`, incluindo configuração de interceptors, retry e observables com RxJS.

---

## Perguntas frequentes

### Como estruturar a integração com a API de CPF no NestJS?

Crie um módulo dedicado (`CpfModule`) com `HttpModule.registerAsync` para configurar o Axios, um service injetável para encapsular as chamadas e um controller com DTOs validados pelo `class-validator`. Essa separação permite reutilizar o `CpfService` em outros módulos da aplicação e facilita a criação de mocks nos testes unitários.

### Qual timeout configurar no HttpModule para a API da CPFHub.io?

A latência média da API é de ~900ms. Configure o timeout do Axios em pelo menos 5.000ms (5 segundos) via `CPFHUB_TIMEOUT` no `.env`. Em produção com alta carga ou conexões instáveis, 8 a 10 segundos evita cancelamentos prematuros que gerariam erros desnecessários para o usuário final.

### A API da CPFHub.io retorna 429 quando o limite mensal é 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 a R$0,15 automaticamente. Por isso, remova o tratamento especial de 429 como "rate limit bloqueante" e monitore o consumo pelo painel em `app.cpfhub.io/settings/billing`.

### Como testar o CpfService sem fazer chamadas reais à API?

Use o sistema de DI do NestJS para substituir o `HttpService` por um mock com `jest.fn()`. O `TestingModule` permite compilar o módulo com providers alternativos, simulando respostas da API sem consumir consultas reais do plano — o que mantém o ambiente de testes isolado e previsível.

### Leia também

- [Como validar CPF no frontend com React e API REST](https://cpfhub.io/blog/como-validar-cpf-no-frontend-com-react-e-api-rest)
- [Como consumir API de CPF em TypeScript com tipagem segura](https://cpfhub.io/blog/como-consumir-api-de-cpf-em-typescript-com-tipagem-segura)
- [Como consumir APIs REST de CPF em Node.js com Axios e Fetch](https://cpfhub.io/blog/como-consumir-apis-rest-de-cpf-em-nodejs-com-axios-e-fetch)
- [Autenticação em APIs REST: como garantir segurança na consulta de CPF](https://cpfhub.io/blog/autenticacao-apis-rest-seguranca-consulta-cpf)

---

## Conclusão

O NestJS oferece a melhor estrutura no ecossistema Node.js para integrar a API da [**CPFHub.io**](https://www.cpfhub.io/)

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/)

