# Como consumir API de CPF em Java com Spring Boot e RestTemplate

> Aprenda a consumir a API de consulta de CPF em Java usando Spring Boot e RestTemplate. Guia completo com exemplos de código e boas práticas.

**Publicado:** 06/01/2025
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/como-consumir-api-de-cpf-em-java-com-spring-boot-e-resttemplate

---


Para consumir a API de CPF da CPFHub.io em Java com Spring Boot, registre o `RestTemplate` como Bean com timeout configurado, injete a API Key via `application.properties` e faça uma chamada GET para `https://api.cpfhub.io/cpf/{CPF}` com o header `x-api-key`. O retorno em JSON contém nome, data de nascimento e gênero do titular em aproximadamente 900ms.

## Introdução

O Java com Spring Boot continua sendo uma das combinações mais utilizadas para desenvolvimento de aplicações corporativas no Brasil. Bancos, seguradoras, fintechs e grandes empresas de tecnologia dependem desse ecossistema para construir sistemas robustos e escaláveis. A validação de CPF via API é uma necessidade recorrente em processos de cadastro, onboarding e verificação de identidade.

---

## Pré-requisitos

* **Java 17+** -- Versão LTS recomendada.
* **Spring Boot 3.x** -- Framework web.
* **Maven ou Gradle** -- Gerenciador de dependências.
* **Conta na CPFHub.io** -- Para obter a chave de API (50 consultas/mês no plano gratuito).

### Dependências Maven

```xml
<dependencies>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 <dependency>
 <groupId>com.fasterxml.jackson.core</groupId>
 <artifactId>jackson-databind</artifactId>
 </dependency>
</dependencies>
```

---

## Modelando a resposta da API

Crie as classes Java que representam a resposta JSON:

```java
import com.fasterxml.jackson.annotation.JsonProperty;

public class CpfResponse {

 @JsonProperty("success")
 private boolean success;

 @JsonProperty("data")
 private CpfData data;

 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; }
}
```

```java
import com.fasterxml.jackson.annotation.JsonProperty;

public class CpfData {

 @JsonProperty("cpf")
 private String cpf;

 @JsonProperty("name")
 private String name;

 @JsonProperty("nameUpper")
 private String nameUpper;

 @JsonProperty("gender")
 private String gender;

 @JsonProperty("birthDate")
 private String birthDate;

 @JsonProperty("day")
 private int day;

 @JsonProperty("month")
 private int month;

 @JsonProperty("year")
 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; }
}
```

Resposta esperada da API:

```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
 }
}
```

---

## Configurando o RestTemplate

Registre o RestTemplate como um Bean com timeout configurado:

```java
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

import java.time.Duration;

@Configuration
public class RestTemplateConfig {

 @Bean
 public RestTemplate restTemplate(RestTemplateBuilder builder) {
 return builder
 .setConnectTimeout(Duration.ofSeconds(5))
 .setReadTimeout(Duration.ofSeconds(10))
 .build();
 }
}
```

---

## Criando o serviço de consulta

```java
import org.springframework.beans.factory.annotation.Value;
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.ResourceAccessException;
import org.springframework.web.client.RestTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Service
public class CpfValidationService {

 private static final Logger log = LoggerFactory.getLogger(
 CpfValidationService.class);

 private final RestTemplate restTemplate;

 @Value("${cpfhub.api-key}")
 private String apiKey;

 @Value("${cpfhub.base-url:https://api.cpfhub.io}")
 private String baseUrl;

 public CpfValidationService(RestTemplate restTemplate) {
 this.restTemplate = restTemplate;
 }

 public CpfData validarCpf(String cpf) {
 String cpfLimpo = cpf.replaceAll("\\D", "");

 if (cpfLimpo.length() != 11) {
 throw new IllegalArgumentException(
 "CPF inválido. Informe 11 dígitos.");
 }

 String url = baseUrl + "/cpf/" + cpfLimpo;

 HttpHeaders headers = new HttpHeaders();
 headers.set("x-api-key", apiKey);
 headers.set("Accept", "application/json");

 HttpEntity<Void> entity = new HttpEntity<>(headers);

 try {
 ResponseEntity<CpfResponse> response = restTemplate.exchange(
 url, HttpMethod.GET, entity, CpfResponse.class);

 CpfResponse body = response.getBody();

 if (body != null && body.isSuccess() && body.getData() != null) {
 log.info("CPF {} validado com sucesso.", cpfLimpo);
 return body.getData();
 }

 log.warn("CPF {} não encontrado.", cpfLimpo);
 return null;

 } catch (ResourceAccessException e) {
 log.error("Timeout ao consultar CPF: {}", cpfLimpo);
 throw new RuntimeException(
 "Tempo limite excedido na consulta de CPF.");
 } catch (HttpClientErrorException e) {
 log.error("Erro HTTP {} ao consultar CPF: {}",
 e.getStatusCode(), cpfLimpo);
 throw new RuntimeException(
 "Erro na consulta de CPF: " + e.getStatusCode());
 }
 }
}
```

---

## Criando o Controller

```java
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
@RequestMapping("/api/cpf")
public class CpfController {

 private final CpfValidationService cpfService;

 public CpfController(CpfValidationService cpfService) {
 this.cpfService = cpfService;
 }

 @GetMapping("/{cpf}")
 public ResponseEntity<?> validar(@PathVariable String cpf) {
 try {
 CpfData resultado = cpfService.validarCpf(cpf);

 if (resultado != null) {
 return ResponseEntity.ok(Map.of(
 "valido", true,
 "dados", resultado
 ));
 }

 return ResponseEntity.status(404).body(Map.of(
 "valido", false,
 "erro", "CPF não encontrado."
 ));
 } catch (IllegalArgumentException e) {
 return ResponseEntity.badRequest().body(Map.of(
 "erro", e.getMessage()
 ));
 } catch (RuntimeException e) {
 return ResponseEntity.status(500).body(Map.of(
 "erro", e.getMessage()
 ));
 }
 }
}
```

---

## Configuração do application.properties

```properties
cpfhub.api-key=SUA_CHAVE_DE_API
cpfhub.base-url=https://api.cpfhub.io
```

---

## Testando a aplicação

Inicie a aplicação Spring Boot e teste com cURL:

```bash
curl -X GET http://localhost:8080/api/cpf/12345678900 \
 -H "Accept: application/json" \
 --max-time 10
```

---

## Boas práticas

* **Injeção de dependência** -- Registre RestTemplate como Bean e injete nos serviços.

* **Timeout** -- Configure connect e read timeout no RestTemplateBuilder.

* **Propriedades externalizadas** -- Use `application.properties` ou variáveis de ambiente para a chave de API.

* **Logging** -- Registre todas as consultas para auditoria com SLF4J.

* **Consumo no plano gratuito** -- O plano gratuito oferece 50 consultas/mês sem cartão de crédito. Ao ultrapassar o limite, a API não bloqueia: cada consulta adicional é cobrada a R$ 0,15. O plano Pro oferece 1.000 consultas por R$ 149/mês com SLA de 99%.

* **Migração para WebClient** -- Para projetos novos, considere usar WebClient (reativo) em vez de RestTemplate, que está em modo de manutenção. Veja a [documentação do Spring WebClient](https://docs.spring.io/spring-framework/reference/web/webflux-webclient.html) para referência.

---

## Perguntas frequentes

### Por que usar RestTemplate em vez de WebClient no Spring Boot?

RestTemplate é síncrono e bloqueante — ideal para aplicações tradicionais que não precisam de programação reativa. Para a maioria dos casos de validação de CPF em fluxos de onboarding ou cadastro, RestTemplate é suficiente e mais simples de configurar. WebClient é recomendado para aplicações reativas com Spring WebFlux ou quando é necessário processar muitas consultas em paralelo.

### Como lidar com erros de timeout ao consultar a API?

Configure `setConnectTimeout` e `setReadTimeout` no `RestTemplateBuilder`. A latência da API da CPFHub.io é de aproximadamente 900ms em condições normais, então um read timeout de 10 segundos é conservador e seguro. Capture `ResourceAccessException` no serviço para tratar timeouts sem derrubar a requisição principal da sua aplicação.

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

Não. A CPFHub.io não bloqueia requisições nem retorna HTTP 429 ao atingir o limite do plano. Quando o limite mensal é ultrapassado, cada consulta adicional é cobrada a R$ 0,15 automaticamente. Você pode acompanhar o consumo em [app.cpfhub.io/settings/billing](https://app.cpfhub.io/settings/billing) para planejar a migração para o plano Pro (1.000 consultas por R$ 149/mês) quando necessário.

### Como externalizar a API Key no Spring Boot para não expô-la no código?

Use `@Value("${cpfhub.api-key}")` no serviço e defina o valor em `application.properties` (ou melhor, em variáveis de ambiente que sobrescrevem as propriedades). Em produção, injete a chave via variável de ambiente (`CPFHUB_API_KEY`) ou use um secret manager como AWS Secrets Manager integrado ao Spring Cloud. Nunca comite a chave em repositórios Git.

### Leia também

- [Como integrar a API de CPF em uma aplicação Spring Boot](https://cpfhub.io/blog/integrar-api-cpf-spring-boot)
- [Como usar RestTemplate e WebClient para consultar CPF via API em Java](https://cpfhub.io/blog/resttemplate-webclient-consultar-cpf-api-java)
- [Como integrar validação de CPF em aplicações Spring WebFlux (reativo)](https://cpfhub.io/blog/como-integrar-validacao-de-cpf-em-aplicacoes-spring-webflux-reativo)
- [10 erros mais comuns ao integrar uma API de CPF e como evitá-los](https://cpfhub.io/blog/10-erros-mais-comuns-ao-integrar-uma-api-de-cpf)

---

## Conclusão

Consumir a API de consulta de CPF da CPFHub.io em Java com Spring Boot e RestTemplate é direto: modele as classes de resposta com Jackson, registre o RestTemplate como Bean com timeout e injete a API Key via propriedades externalizadas. O serviço resultante valida CPFs em aproximadamente 900ms e pode ser reutilizado em qualquer ponto da aplicação — desde o onboarding até a emissão de documentos.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) — 50 consultas mensais gratuitas, sem cartão de crédito — e integre a validação de CPF no seu projeto Spring Boot hoje mesmo.

