# Como Consumir a API de CPF em Java Usando HttpClient

> Aprenda a consumir a API de CPF em Java usando o HttpClient nativo do Java 11+, com requisições síncronas, assíncronas e tratamento de erros.

**Publicado:** 10/09/2024
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/consumir-api-cpf-java-httpclient

---


Para consumir a API de CPF em Java usando o HttpClient nativo, instancie um `HttpClient` via builder pattern (disponível desde o Java 11), construa a requisição com o header `x-api-key` e o endpoint `GET https://api.cpfhub.io/cpf/{CPF}`, depois processe a resposta JSON. O HttpClient suporta tanto chamadas síncronas com `send()` quanto assíncronas com `sendAsync()`, sem necessidade de dependências externas para a camada HTTP.

## Introdução

A partir do Java 11, a linguagem oferece um HttpClient nativo, moderno e performático que substitui a necessidade de bibliotecas externas como Apache HttpClient ou OkHttp para chamadas HTTP simples. O novo HttpClient suporta HTTP/2, requisições assíncronas e um modelo fluente de configuração.

## Configurando o HttpClient

O HttpClient do Java 11+ é criado via builder pattern e pode ser reutilizado para múltiplas requisições.

```java
import java.net.http.HttpClient;
import java.time.Duration;

public class CpfHubClientConfig {

 public static HttpClient criarHttpClient() {
 return HttpClient.newBuilder()
 .version(HttpClient.Version.HTTP_2)
 .connectTimeout(Duration.ofSeconds(5))
 .followRedirects(HttpClient.Redirect.NORMAL)
 .build();
 }
}
```

| Configuração | Valor | Descrição |
|---|---|---|
| Versão HTTP | HTTP/2 | Protocolo mais eficiente |
| Connect Timeout | 5 segundos | Tempo máximo para estabelecer conexão |
| Follow Redirects | NORMAL | Segue redirecionamentos padrão |
| Thread Pool | Padrão (ForkJoinPool) | Pool de threads para requisições async |

---

## Consulta síncrona

A abordagem síncrona é a mais simples e adequada para chamadas individuais.

```java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class CpfHubClient {

 private final HttpClient httpClient;
 private final String apiKey;
 private final String baseUrl;
 private final ObjectMapper objectMapper;

 public CpfHubClient(String apiKey) {
 this.httpClient = CpfHubClientConfig.criarHttpClient();
 this.apiKey = apiKey;
 this.baseUrl = "https://api.cpfhub.io";
 this.objectMapper = new ObjectMapper();
 }

 public DadosCpf consultar(String cpf) throws Exception {
 String cpfLimpo = cpf.replaceAll("\\D", "");

 if (cpfLimpo.length() != 11) {
 throw new IllegalArgumentException(
 "CPF deve conter 11 digitos"
 );
 }

 HttpRequest request = HttpRequest.newBuilder()
 .uri(URI.create(baseUrl + "/cpf/" + cpfLimpo))
 .header("x-api-key", apiKey)
 .header("Content-Type", "application/json")
 .timeout(Duration.ofSeconds(10))
 .GET()
 .build();

 HttpResponse<String> response = httpClient.send(
 request,
 HttpResponse.BodyHandlers.ofString()
 );

 return processarResposta(response);
 }

 private DadosCpf processarResposta(
 HttpResponse<String> response) throws Exception {

 if (response.statusCode() == 200) {
 JsonNode root = objectMapper.readTree(response.body());

 if (root.get("success").asBoolean()) {
 JsonNode data = root.get("data");
 return new DadosCpf(
 data.get("cpf").asText(),
 data.get("name").asText(),
 data.get("nameUpper").asText(),
 data.get("gender").asText(),
 data.get("birthDate").asText(),
 data.get("day").asInt(),
 data.get("month").asInt(),
 data.get("year").asInt()
 );
 }
 throw new CpfNaoEncontradoException("CPF nao encontrado");
 }

 if (response.statusCode() == 401) {
 throw new AuthenticationException("API key invalida");
 }

 throw new ApiException(
 "Erro na API: status " + response.statusCode()
 );
 }
}
```

---

## Modelo de dados e exceções

Defina o record (Java 16+) ou classe para os dados retornados pela API.

```java
// DadosCpf.java
public record DadosCpf(
 String cpf,
 String name,
 String nameUpper,
 String gender,
 String birthDate,
 int day,
 int month,
 int year
) {
 public boolean isMasculino() {
 return "M".equals(gender);
 }

 public boolean isFeminino() {
 return "F".equals(gender);
 }
}

// Exceções customizadas
public class ApiException extends RuntimeException {
 public ApiException(String message) { super(message); }
}

public class CpfNaoEncontradoException extends ApiException {
 public CpfNaoEncontradoException(String message) { super(message); }
}

public class AuthenticationException extends ApiException {
 public AuthenticationException(String message) { super(message); }
}
```

| Exceção | Status HTTP | Retentar |
|---|---|---|
| CpfNaoEncontradoException | 200 (success=false) | Não |
| AuthenticationException | 401 | Não |
| ApiException | 5xx | Sim, com backoff |

---

## Consulta assíncrona

O HttpClient oferece suporte nativo a requisições assíncronas via CompletableFuture.

```java
import java.util.concurrent.CompletableFuture;

public class CpfHubAsyncClient {

 private final HttpClient httpClient;
 private final String apiKey;
 private final ObjectMapper objectMapper;

 public CpfHubAsyncClient(String apiKey) {
 this.httpClient = CpfHubClientConfig.criarHttpClient();
 this.apiKey = apiKey;
 this.objectMapper = new ObjectMapper();
 }

 public CompletableFuture<DadosCpf> consultarAsync(String cpf) {
 String cpfLimpo = cpf.replaceAll("\\D", "");

 HttpRequest request = HttpRequest.newBuilder()
 .uri(URI.create("https://api.cpfhub.io/cpf/" + cpfLimpo))
 .header("x-api-key", apiKey)
 .timeout(Duration.ofSeconds(10))
 .GET()
 .build();

 return httpClient.sendAsync(
 request,
 HttpResponse.BodyHandlers.ofString()
 ).thenApply(response -> {
 try {
 JsonNode root = objectMapper.readTree(response.body());
 if (root.get("success").asBoolean()) {
 JsonNode data = root.get("data");
 return new DadosCpf(
 data.get("cpf").asText(),
 data.get("name").asText(),
 data.get("nameUpper").asText(),
 data.get("gender").asText(),
 data.get("birthDate").asText(),
 data.get("day").asInt(),
 data.get("month").asInt(),
 data.get("year").asInt()
 );
 }
 throw new CpfNaoEncontradoException("CPF nao encontrado");
 } catch (Exception e) {
 throw new RuntimeException(e);
 }
 });
 }
}

// Uso
CpfHubAsyncClient client = new CpfHubAsyncClient("SUA_API_KEY");

client.consultarAsync("12345678901")
 .thenAccept(dados -> System.out.println("Nome: " + dados.name()))
 .exceptionally(erro -> {
 System.err.println("Erro: " + erro.getMessage());
 return null;
 });
```

---

## Exemplo completo de uso

Um exemplo completo demonstrando todas as funcionalidades do cliente.

```java
public class Main {

 public static void main(String[] args) {
 String apiKey = System.getenv("CPFHUB_API_KEY");
 CpfHubClient client = new CpfHubClient(apiKey);

 try {
 DadosCpf dados = client.consultar("123.456.789-01");
 System.out.println("CPF: " + dados.cpf());
 System.out.println("Nome: " + dados.name());
 System.out.println("Genero: " + dados.gender());
 System.out.println("Nascimento: " + dados.birthDate());
 System.out.printf("Nascido em %d/%d/%d%n",
 dados.day(), dados.month(), dados.year());
 } catch (CpfNaoEncontradoException e) {
 System.out.println("CPF nao encontrado na base.");
 } catch (AuthenticationException e) {
 System.out.println("Erro de autenticacao. Verifique a API key.");
 } catch (Exception e) {
 System.out.println("Erro inesperado: " + e.getMessage());
 }
 }
}
```

---

## Perguntas frequentes

### O HttpClient nativo do Java 11 é suficiente para consumir a API de CPF em produção?
Sim. O `java.net.http.HttpClient` suporta HTTP/2, timeouts configuráveis, requisições assíncronas via `CompletableFuture` e reutilização de conexões — tudo o que é necessário para consumir a API CPFHub.io de forma eficiente em produção, sem adicionar dependências externas ao projeto.

### Como configurar timeout para evitar que a aplicação trave em chamadas lentas?
Configure dois timeouts: `connectTimeout` no builder do `HttpClient` (recomendado: 5 segundos) e `timeout` no `HttpRequest.newBuilder()` (recomendado: 10 segundos). A latência típica da API é de ~900ms, então 10 segundos é margem suficiente para acomodar variações de rede sem prejudicar a experiência do usuário.

### Como autenticar as requisições na API CPFHub.io usando Java HttpClient?
Adicione o header `x-api-key` com sua chave de API ao construir o `HttpRequest`: `.header("x-api-key", apiKey)`. A chave pode ser armazenada em variável de ambiente (`System.getenv("CPFHUB_API_KEY")`) para evitar expô-la no código-fonte, seguindo as boas práticas de segurança da [OWASP](https://owasp.org/www-project-top-ten/).

### Qual a diferença entre `send()` síncrono e `sendAsync()` na integração com a API de CPF?
`send()` bloqueia a thread atual até receber a resposta — ideal para validações pontuais no fluxo de cadastro. `sendAsync()` retorna um `CompletableFuture<HttpResponse>` e não bloqueia a thread — ideal para processar múltiplos CPFs em paralelo ou integrar com frameworks reativos. Para validações em batch, `sendAsync()` com coleta de futures é significativamente mais eficiente.

### Leia também

- [Diferença entre validação de CPF e consulta de CPF: quando usar cada uma](https://cpfhub.io/blog/diferenca-entre-validacao-de-cpf-e-consulta-de-cpf-quando-usar-cada-uma)
- [API de CPF grátis para desenvolvedores: como começar em 5 minutos](https://cpfhub.io/blog/api-cpf-gratis-desenvolvedores-comecar-5-minutos)
- [Onboarding digital em fintechs: como validar CPF em menos de 30 segundos](https://cpfhub.io/blog/onboarding-digital-em-fintechs-como-validar-cpf-em-menos-de-30-segundos)
- [KYC no Brasil: quais setores são obrigados a validar CPF por lei](https://cpfhub.io/blog/kyc-no-brasil-quais-setores-sao-obrigados-a-validar-cpf-por-lei)

---

## Conclusão

O HttpClient nativo do Java 11+ é uma solução completa e moderna para consumir a API de CPF, sem necessidade de dependências externas para a camada HTTP. Com suporte a HTTP/2, requisições assíncronas e timeout configurável, o cliente atende desde chamadas individuais simples até cenários de alta concorrência. O tratamento de erros com exceções customizadas garante que cada tipo de falha seja tratado de forma apropriada.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) — 50 consultas mensais gratuitas, sem cartão de crédito — e comece a validar CPFs em Java com o HttpClient nativo ainda hoje.

