# Como criar uma Minimal API em .NET para consulta de CPF

> Crie uma Minimal API em .NET para consulta de CPF com poucos arquivos, validação e integração com a API do CPFHub.

**Publicado:** 22/10/2024
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/como-criar-minimal-api-dotnet-consulta-cpf

---


As Minimal APIs do .NET permitem criar um endpoint de consulta de CPF com apenas um arquivo `Program.cs`, integrando diretamente com a CPFHub.io via `HttpClient` e entregando resposta JSON em ~900ms. A abordagem elimina controllers, reduz a cerimônia de configuração e é ideal para microsserviços e provas de conceito que precisam ir a produção rapidamente.

## Introdução

As Minimal APIs do .NET permitem criar endpoints HTTP com o mínimo de cerimônia, eliminando a necessidade de controllers e configurações extensas. Este guia mostra como construir um microsserviço funcional em .NET, integrado com o serviço do CPFHub.io.

---

## Estrutura do projeto

Crie o projeto e instale as dependências necessárias:

```csharp
dotnet new web -n CpfMinimalApi
cd CpfMinimalApi
```

A principal vantagem das Minimal APIs é que todo o código pode ser organizado em poucos arquivos, mantendo a simplicidade sem sacrificar funcionalidade.

| Característica | Minimal API | Controller-based API |
|---|---|---|
| Arquivos necessários | 1-3 | 5+ |
| Configuração inicial | Mínima | Extensa |
| Performance | Levemente superior | Padrão |
| Curva de aprendizado | Baixa | Moderada |
| Ideal para | Microsserviços | Aplicações grandes |

---

## Definindo os modelos

Utilize records para definir os modelos de forma concisa e imutável:

```csharp
public record CpfResponse(bool Success, CpfData Data);

public record CpfData(
 string Cpf,
 string Name,
 string NameUpper,
 string Gender,
 string BirthDate,
 string Day,
 string Month,
 string Year
);

public record CpfResult(
 bool Valid,
 string Cpf,
 string? Name,
 string? BirthDate,
 string? Gender,
 string Message
);

public record ErrorResponse(string Message, int StatusCode);
```

---

## Construindo a Minimal API completa

No arquivo `Program.cs`, configure todos os serviços e endpoints:

```csharp
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpClient("CpfHub", client =>
{
 client.BaseAddress = new Uri("https://api.cpfhub.io/");
 client.DefaultRequestHeaders.Add("x-api-key",
 builder.Configuration["CpfHub:ApiKey"]);
 client.Timeout = TimeSpan.FromSeconds(10);
});

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
 app.UseSwagger();
 app.UseSwaggerUI();
}

app.MapGet("/api/cpf/{cpf}", async (
 string cpf,
 IHttpClientFactory httpClientFactory) =>
{
 var cpfLimpo = new string(cpf.Where(char.IsDigit).ToArray());

 if (cpfLimpo.Length != 11)
 return Results.BadRequest(new ErrorResponse(
 "CPF deve conter exatamente 11 dígitos", 400));

 var client = httpClientFactory.CreateClient("CpfHub");

 try
 {
 var response = await client.GetAsync($"cpf/{cpfLimpo}");

 if (!response.IsSuccessStatusCode)
 return Results.NotFound(new ErrorResponse(
 "CPF não encontrado", 404));

 var dados = await response.Content
 .ReadFromJsonAsync<CpfResponse>();

 if (dados is not { Success: true })
 return Results.NotFound(new ErrorResponse(
 "CPF não encontrado na base", 404));

 return Results.Ok(new CpfResult(
 true, dados.Data.Cpf, dados.Data.Name,
 dados.Data.BirthDate, dados.Data.Gender,
 "CPF encontrado com sucesso"
 ));
 }
 catch (TaskCanceledException)
 {
 return Results.StatusCode(504);
 }
 catch (HttpRequestException)
 {
 return Results.StatusCode(502);
 }
})
.WithName("ConsultarCpf")
.WithOpenApi()
.Produces<CpfResult>(200)
.Produces<ErrorResponse>(400)
.Produces<ErrorResponse>(404);

app.Run();
```

---

## Adicionando validação e middleware

Crie um filtro de endpoint para validar o CPF antes de processar a requisição:

```csharp
app.MapGet("/api/cpf/validar/{cpf}", (string cpf) =>
{
 var cpfLimpo = new string(cpf.Where(char.IsDigit).ToArray());

 if (cpfLimpo.Length != 11)
 return Results.BadRequest(new { valid = false, message = "CPF incompleto" });

 if (cpfLimpo.Distinct().Count() == 1)
 return Results.BadRequest(new { valid = false, message = "CPF com dígitos repetidos" });

 var soma = 0;
 for (int i = 0; i < 9; i++)
 soma += (cpfLimpo[i] - '0') * (10 - i);
 var d1 = soma % 11 < 2 ? 0 : 11 - (soma % 11);

 soma = 0;
 for (int i = 0; i < 10; i++)
 soma += (cpfLimpo[i] - '0') * (11 - i);
 var d2 = soma % 11 < 2 ? 0 : 11 - (soma % 11);

 var valido = cpfLimpo[9] - '0' == d1 && cpfLimpo[10] - '0' == d2;

 return valido
 ? Results.Ok(new { valid = true, message = "CPF válido" })
 : Results.BadRequest(new { valid = false, message = "Dígitos verificadores inválidos" });
})
.WithName("ValidarCpf")
.WithOpenApi();
```

---

## Testando com HTTP files

O .NET suporta arquivos `.http` para testar endpoints diretamente no Visual Studio ou VS Code. Consulte a [documentação oficial da Microsoft](https://learn.microsoft.com/pt-br/aspnet/core/test/http-files) para mais detalhes sobre o formato:

```csharp
// Arquivo: requests.http

### Consultar CPF
GET https://localhost:5001/api/cpf/12345678900

### Validar formato do CPF
GET https://localhost:5001/api/cpf/validar/12345678900

### CPF inválido
GET https://localhost:5001/api/cpf/validar/11111111111
```

---

## Perguntas frequentes

### A CPFHub.io retorna HTTP 429 quando o limite de consultas é atingido?

Não. A API nunca retorna HTTP 429 nem bloqueia requisições. Ao atingir o limite do plano (50 consultas/mês no gratuito ou 1.000 no Pro), as consultas adicionais são cobradas a R$0,15 cada, garantindo que o microsserviço .NET continue funcionando sem interrupções. O controle de consumo fica disponível em [app.cpfhub.io/settings/billing](https://app.cpfhub.io/settings/billing).

### Como armazenar a API key com segurança em uma Minimal API .NET?

Use `builder.Configuration["CpfHub:ApiKey"]` combinado com `dotnet user-secrets` em desenvolvimento e variáveis de ambiente (ou Azure Key Vault) em produção. Nunca coloque a chave diretamente no código-fonte ou em arquivos `appsettings.json` versionados. O `IHttpClientFactory` já injeta o header `x-api-key` de forma centralizada, evitando duplicação.

### Qual é a latência esperada da API CPFHub.io em um microsserviço .NET?

A latência média da CPFHub.io é ~900ms por consulta. Configure o `Timeout` do `HttpClient` para pelo menos 10 segundos para absorver variações de rede. O tratamento de `TaskCanceledException` no exemplo acima já garante que timeouts sejam propagados como HTTP 504, mantendo a API bem comportada.

### Posso usar essa Minimal API como back-end intermediário para proteger a chave de API?

Sim, e é a abordagem recomendada. Expor a API key diretamente no front-end ou em aplicativos móveis é um risco de segurança. O microsserviço .NET recebe o CPF do cliente, chama a CPFHub.io com a chave guardada em segredos e devolve apenas os dados necessários, sem expor credenciais.

### Leia também

- [Como consumir a API de CPF em C# usando HttpClient](https://cpfhub.io/blog/como-consumir-api-cpf-csharp-httpclient)
- [Como integrar a API de CPF em uma aplicação ASP.NET Core](https://cpfhub.io/blog/como-integrar-api-cpf-aspnet-core)
- [Como criar um serviço de validação de CPF em .NET com injeção de dependência](https://cpfhub.io/blog/como-criar-servico-validacao-cpf-dotnet-injecao-dependencia)
- [SLA de API de CPF: níveis de disponibilidade e o que exigir do seu provedor](https://cpfhub.io/blog/sla-api-cpf-niveis-disponibilidade)

---

## Conclusão

As Minimal APIs do .NET são ideais para criar microsserviços focados como a consulta de CPF. Com poucas linhas de código, você obtém um endpoint funcional, documentado com Swagger e pronto para produção.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) — 50 consultas mensais gratuitas, sem cartão de crédito — e integre a consulta de CPF ao seu projeto .NET em menos de duas horas.

