Para integrar a API de CPF em uma aplicação Spring Boot, configure o RestTemplate com os timeouts e o header x-api-key, crie um service que encapsula a chamada para GET https://api.cpfhub.io/cpf/{CPF} e trate as exceções por tipo de resposta. A estrutura completa inclui propriedades externalizadas via application.yml, DTOs tipados e um @RestControllerAdvice para tratamento centralizado de erros.
Introdução
O Spring Boot é o framework mais utilizado para desenvolvimento de aplicações Java empresariais, e integrar APIs externas é uma das tarefas mais comuns nesse ecossistema.
Configuração do projeto
Comece configurando as dependências e propriedades da aplicação.
// pom.xml (dependências relevantes)
// spring-boot-starter-web
// spring-boot-starter-validation
// jackson-databind
// lombok (opcional)
// application.yml
// cpfhub:
// api-key: ${CPFHUB_API_KEY}
// base-url: https://api.cpfhub.io
// timeout:
// connect: 5000
// read: 10000
// CpfHubProperties.java
package com.exemplo.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "cpfhub")
public class CpfHubProperties {
private String apiKey;
private String baseUrl = "https://api.cpfhub.io";
private Timeout timeout = new Timeout();
public static class Timeout {
private int connect = 5000;
private int read = 10000;
// Getters e setters
public int getConnect() { return connect; }
public void setConnect(int connect) { this.connect = connect; }
public int getRead() { return read; }
public void setRead(int read) { this.read = read; }
}
// Getters e setters
public String getApiKey() { return apiKey; }
public void setApiKey(String apiKey) { this.apiKey = apiKey; }
public String getBaseUrl() { return baseUrl; }
public void setBaseUrl(String baseUrl) { this.baseUrl = baseUrl; }
public Timeout getTimeout() { return timeout; }
public void setTimeout(Timeout timeout) { this.timeout = timeout; }
}
| Propriedade | Valor Padrão | Descrição |
|---|---|---|
| cpfhub.api-key | (variável de ambiente) | Chave de autenticação da API |
| cpfhub.base-url | https://api.cpfhub.io | URL base da API |
| cpfhub.timeout.connect | 5000ms | Timeout de conexão |
| cpfhub.timeout.read | 10000ms | Timeout de leitura |
Modelos de dados
Defina os DTOs para a comunicação com a API.
// CpfResponse.java
package com.exemplo.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
public class CpfResponse {
private boolean success;
private CpfData data;
// Getters e setters
public boolean isSuccess() { return success; }
public void setSuccess(boolean success) { this.success = success; }
public CpfData getData() { return data; }
public void setData(CpfData data) { this.data = data; }
}
// CpfData.java
public class CpfData {
private String cpf;
private String name;
private String nameUpper;
private String gender;
private String birthDate;
private int day;
private int month;
private int year;
// Getters e setters
public String getCpf() { return cpf; }
public void setCpf(String cpf) { this.cpf = cpf; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getNameUpper() { return nameUpper; }
public void setNameUpper(String nameUpper) { this.nameUpper = nameUpper; }
public String getGender() { return gender; }
public void setGender(String gender) { this.gender = gender; }
public String getBirthDate() { return birthDate; }
public void setBirthDate(String birthDate) { this.birthDate = birthDate; }
public int getDay() { return day; }
public void setDay(int day) { this.day = day; }
public int getMonth() { return month; }
public void setMonth(int month) { this.month = month; }
public int getYear() { return year; }
public void setYear(int year) { this.year = year; }
}
Service layer
O service encapsula a lógica de chamada à API e tratamento de erros.
// CpfService.java
package com.exemplo.service;
import com.exemplo.config.CpfHubProperties;
import com.exemplo.dto.CpfData;
import com.exemplo.dto.CpfResponse;
import com.exemplo.exception.CpfNaoEncontradoException;
import com.exemplo.exception.CpfHubApiException;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import java.time.Duration;
@Service
public class CpfService {
private final RestTemplate restTemplate;
private final CpfHubProperties properties;
public CpfService(
RestTemplateBuilder builder,
CpfHubProperties properties) {
this.properties = properties;
this.restTemplate = builder
.setConnectTimeout(Duration.ofMillis(
properties.getTimeout().getConnect()))
.setReadTimeout(Duration.ofMillis(
properties.getTimeout().getRead()))
.build();
}
public CpfData consultar(String cpf) {
String cpfLimpo = cpf.replaceAll("\\D", "");
validarFormatoCpf(cpfLimpo);
HttpHeaders headers = new HttpHeaders();
headers.set("x-api-key", properties.getApiKey());
HttpEntity<Void> entity = new HttpEntity<>(headers);
try {
ResponseEntity<CpfResponse> response = restTemplate.exchange(
properties.getBaseUrl() + "/cpf/" + cpfLimpo,
HttpMethod.GET,
entity,
CpfResponse.class
);
CpfResponse body = response.getBody();
if (body != null && body.isSuccess()) {
return body.getData();
}
throw new CpfNaoEncontradoException(
"CPF " + cpfLimpo + " nao encontrado"
);
} catch (HttpClientErrorException.Unauthorized e) {
throw new CpfHubApiException("API key invalida");
} catch (HttpClientErrorException e) {
throw new CpfHubApiException(
"Erro na API: " + e.getStatusCode()
);
}
}
private void validarFormatoCpf(String cpf) {
if (cpf == null || !cpf.matches("\\d{11}")) {
throw new IllegalArgumentException(
"CPF deve conter 11 digitos"
);
}
}
}
Controller REST
O controller expõe o endpoint para consulta de CPF.
// CpfController.java
package com.exemplo.controller;
import com.exemplo.dto.CpfData;
import com.exemplo.service.CpfService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/api/cpf")
public class CpfController {
private final CpfService cpfService;
public CpfController(CpfService cpfService) {
this.cpfService = cpfService;
}
@GetMapping("/{cpf}")
public ResponseEntity<Map<String, Object>> consultar(
@PathVariable String cpf) {
CpfData dados = cpfService.consultar(cpf);
return ResponseEntity.ok(Map.of(
"sucesso", true,
"dados", dados
));
}
}
// GlobalExceptionHandler.java
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(CpfNaoEncontradoException.class)
public ResponseEntity<Map<String, String>> handleCpfNaoEncontrado(
CpfNaoEncontradoException ex) {
return ResponseEntity.status(404).body(Map.of(
"erro", ex.getMessage()
));
}
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<Map<String, String>> handleArgumentoInvalido(
IllegalArgumentException ex) {
return ResponseEntity.badRequest().body(Map.of(
"erro", ex.getMessage()
));
}
@ExceptionHandler(CpfHubApiException.class)
public ResponseEntity<Map<String, String>> handleApiException(
CpfHubApiException ex) {
return ResponseEntity.status(502).body(Map.of(
"erro", ex.getMessage()
));
}
}
| Endpoint | Método | Descrição |
|---|---|---|
/api/cpf/{cpf} | GET | Consulta um CPF via API |
| Resposta 200 | - | CPF encontrado com dados |
| Resposta 400 | - | CPF em formato inválido |
| Resposta 404 | - | CPF não encontrado |
| Resposta 502 | - | Erro na comunicação com a API |
Testes
Escreva testes unitários e de integração para garantir a qualidade.
// CpfServiceTest.java
@SpringBootTest
class CpfServiceTest {
@MockBean
private RestTemplate restTemplate;
@Autowired
private CpfService cpfService;
@Test
void deveRetornarDadosQuandoCpfEncontrado() {
CpfResponse response = new CpfResponse();
response.setSuccess(true);
CpfData data = new CpfData();
data.setCpf("12345678901");
data.setName("Joao da Silva");
data.setGender("M");
response.setData(data);
// Configurar mock...
CpfData resultado = cpfService.consultar("12345678901");
assertEquals("Joao da Silva", resultado.getName());
}
@Test
void deveLancarExcecaoQuandoCpfInvalido() {
assertThrows(
IllegalArgumentException.class,
() -> cpfService.consultar("123")
);
}
}
Perguntas frequentes
Por que usar um @ConfigurationProperties para as configurações da API de CPF no Spring Boot?
Externalizar as configurações via @ConfigurationProperties permite alterar a API key, a URL base e os timeouts sem recompilar a aplicação — basta atualizar variáveis de ambiente ou o application.yml. Isso é essencial para ambientes distintos (dev, staging, prod) e para rotação segura de chaves de autenticação seguindo as boas práticas da OWASP.
Qual a diferença entre RestTemplate e WebClient para consumir a API de CPF no Spring Boot?
O RestTemplate é síncrono e bloqueante — adequado para aplicações Spring MVC tradicionais. O WebClient é não bloqueante e faz parte do Spring WebFlux — indicado para aplicações reativas. Para a maioria dos cenários de validação de CPF em cadastro ou checkout, o RestTemplate com timeout configurável é suficiente e mais simples de testar.
Como tratar o caso em que o CPF não é encontrado na API?
Quando success: false na resposta, lance uma exceção tipada (ex.: CpfNaoEncontradoException) e capture-a no @RestControllerAdvice para retornar HTTP 404 com mensagem clara ao cliente da sua API. Não trate como erro de sistema — é um resultado de negócio esperado que deve ser comunicado de forma limpa.
A API de CPF pode bloquear minha aplicação por volume de chamadas?
Não. A API CPFHub.io não bloqueia por volume — quando o limite do plano é ultrapassado, cada consulta extra é cobrada a R$0,15 sem interrupção do serviço. Planeje o dimensionamento pelo custo, não por disponibilidade. Para volumes elevados, o plano Pro oferece 1.000 consultas mensais por R$149 com a mesma política de excedente.
Conclusão
Integrar a API de CPF em uma aplicação Spring Boot segue as melhores práticas do ecossistema Spring: configuração externalizada, injeção de dependência, service layer e tratamento centralizado de exceções. Essa abordagem garante que a integração seja testável, manutenível e resiliente. O uso de RestTemplate com timeout configurável e headers de autenticação torna a comunicação com a API segura e eficiente.
Cadastre-se em cpfhub.io — 50 consultas mensais gratuitas, sem cartão de crédito — e integre a validação de CPF na sua aplicação Spring Boot em menos de 30 minutos.
CPFHub.io
Pronto para integrar a API?
50 consultas gratuitas para testar agora. Sem cartão de crédito. Acesso imediato à documentação.
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.



