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.

Redação CPFHub.io
Redação CPFHub.io
··7 min de leitura
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

<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:

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

{
    "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:

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

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

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

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:

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 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 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.


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 — 50 consultas mensais gratuitas, sem cartão de crédito — e integre a validação de CPF no seu projeto Spring Boot hoje mesmo.

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