Como integrar validação de CPF em Azure Functions com C#

Aprenda a criar uma Azure Function em C# que consome a API de CPF da CPFHub.io com HttpClient, Key Vault e deploy automatizado.

Redação CPFHub.io
Redação CPFHub.io
··7 min de leitura
Como integrar validação de CPF em Azure Functions com C#

Para integrar validação de CPF em Azure Functions com C#, crie um HTTP trigger que recebe o número do documento via rota, consulta a API da CPFHub.io usando HttpClient com o header x-api-key e retorna os dados do titular em JSON. A chave de API deve ser armazenada no Azure Key Vault e injetada via DefaultAzureCredential durante a inicialização do host. A documentação oficial das Azure Functions cobre as opções de trigger HTTP, injeção de dependência e planos de consumo disponíveis para o ecossistema .NET.


Estrutura do projeto

Crie o projeto usando o Azure Functions Core Tools:

func init CpfValidator --dotnet --worker-runtime dotnet-isolated
cd CpfValidator
dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Http
dotnet add package Azure.Identity
dotnet add package Azure.Security.KeyVault.Secrets

A estrutura resultante:

CpfValidator/
    Models/
    CpfApiResponse.cs
    CpfValidationResult.cs
    Services/
    CpfHubService.cs
    Functions/
    ValidarCpfFunction.cs
    Program.cs
    host.json
    local.settings.json

Modelos de dados

Defina os modelos que representam a resposta da API e o resultado da validação:

// Models/CpfApiResponse.cs
using System.Text.Json.Serialization;

namespace CpfValidator.Models;

public class CpfApiResponse
{
    [JsonPropertyName("success")]
    public bool Success { get; set; }

    [JsonPropertyName("data")]
    public CpfData? Data { get; set; }
}

public class CpfData
{
    [JsonPropertyName("cpf")]
    public string Cpf { get; set; } = string.Empty;

    [JsonPropertyName("name")]
    public string Name { get; set; } = string.Empty;

    [JsonPropertyName("nameUpper")]
    public string NameUpper { get; set; } = string.Empty;

    [JsonPropertyName("gender")]
    public string Gender { get; set; } = string.Empty;

    [JsonPropertyName("birthDate")]
    public string BirthDate { get; set; } = string.Empty;

    [JsonPropertyName("day")]
    public int Day { get; set; }

    [JsonPropertyName("month")]
    public int Month { get; set; }

    [JsonPropertyName("year")]
    public int Year { get; set; }
}

public class CpfValidationResult
{
    public bool Valido { get; set; }
    public string? Nome { get; set; }
    public string? Genero { get; set; }
    public string? DataNascimento { get; set; }
    public string? Erro { get; set; }
}

Serviço de consulta de CPF

O serviço encapsula a lógica de comunicação com a API, utilizando HttpClient com timeout configurado:

// Services/CpfHubService.cs
using System.Net.Http.Json;
using System.Text.RegularExpressions;
using CpfValidator.Models;
using Microsoft.Extensions.Logging;

namespace CpfValidator.Services;

public interface ICpfHubService
{
    Task<CpfValidationResult> ConsultarAsync(string cpf);
}

public class CpfHubService : ICpfHubService
{
    private readonly HttpClient _httpClient;
    private readonly ILogger<CpfHubService> _logger;
    private const string BaseUrl = "https://api.cpfhub.io/cpf";

    public CpfHubService(HttpClient httpClient, ILogger<CpfHubService> logger)
    {
    _httpClient = httpClient;
    _httpClient.Timeout = TimeSpan.FromSeconds(10);
    _logger = logger;
    }

    public async Task<CpfValidationResult> ConsultarAsync(string cpf)
    {
    var cpfLimpo = Regex.Replace(cpf, @"\D", "");

    if (cpfLimpo.Length != 11)
    {
    return new CpfValidationResult
    {
    Valido = false,
    Erro = "CPF deve conter 11 digitos"
    };
    }

    if (cpfLimpo.Distinct().Count() == 1)
    {
    return new CpfValidationResult
    {
    Valido = false,
    Erro = "CPF invalido"
    };
    }

    try
    {
    using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));

    var response = await _httpClient.GetAsync(
    $"{BaseUrl}/{cpfLimpo}",
    cts.Token
    );

    response.EnsureSuccessStatusCode();

    var resultado = await response.Content
    .ReadFromJsonAsync<CpfApiResponse>(cancellationToken: cts.Token);

    if (resultado is null || !resultado.Success || resultado.Data is null)
    {
    return new CpfValidationResult
    {
    Valido = false,
    Erro = "CPF nao encontrado"
    };
    }

    return new CpfValidationResult
    {
    Valido = true,
    Nome = resultado.Data.Name,
    Genero = resultado.Data.Gender,
    DataNascimento = resultado.Data.BirthDate
    };
    }
    catch (TaskCanceledException)
    {
    _logger.LogWarning("Timeout na consulta do CPF {Cpf}", cpfLimpo);
    return new CpfValidationResult
    {
    Valido = false,
    Erro = "Timeout na consulta de CPF"
    };
    }
    catch (HttpRequestException ex)
    {
    _logger.LogError(ex, "Erro HTTP na consulta do CPF {Cpf}", cpfLimpo);
    return new CpfValidationResult
    {
    Valido = false,
    Erro = $"Erro na comunicacao com a API: {ex.Message}"
    };
    }
    }
}

Configuração com injecao de dependência

O Program.cs configura o HttpClient com a chave de API recuperada do Key Vault:

// Program.cs
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
using CpfValidator.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices((context, services) =>
    {
    var keyVaultUrl = context.Configuration["KeyVaultUrl"];
    string apiKey;

    if (!string.IsNullOrEmpty(keyVaultUrl))
    {
    var secretClient = new SecretClient(
    new Uri(keyVaultUrl),
    new DefaultAzureCredential()
    );
    var secret = secretClient.GetSecret("cpfhub-api-key");
    apiKey = secret.Value.Value;
    }
    else
    {
    apiKey = context.Configuration["CPFHUB_API_KEY"]
    ?? throw new InvalidOperationException(
    "CPFHUB_API_KEY nao configurada"
    );
    }

    services.AddHttpClient<ICpfHubService, CpfHubService>(client =>
    {
    client.DefaultRequestHeaders.Add("x-api-key", apiKey);
    client.DefaultRequestHeaders.Add("Accept", "application/json");
    });
    })
    .Build();

host.Run();

Azure Function HTTP trigger

A função HTTP que expoe o endpoint de validação:

// Functions/ValidarCpfFunction.cs
using System.Net;
using CpfValidator.Services;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;

namespace CpfValidator.Functions;

public class ValidarCpfFunction
{
    private readonly ICpfHubService _cpfService;
    private readonly ILogger<ValidarCpfFunction> _logger;

    public ValidarCpfFunction(
    ICpfHubService cpfService,
    ILogger<ValidarCpfFunction> logger)
    {
    _cpfService = cpfService;
    _logger = logger;
    }

    [Function("ValidarCpf")]
    public async Task<HttpResponseData> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get",
    Route = "cpf/{cpfNumero}")] HttpRequestData req,
    string cpfNumero)
    {
    _logger.LogInformation("Consulta de CPF recebida: {Cpf}",
    cpfNumero?[..Math.Min(3, cpfNumero?.Length ?? 0)] + "***");

    if (string.IsNullOrEmpty(cpfNumero))
    {
    var badRequest = req.CreateResponse(HttpStatusCode.BadRequest);
    await badRequest.WriteAsJsonAsync(new { erro = "CPF e obrigatorio" });
    return badRequest;
    }

    var resultado = await _cpfService.ConsultarAsync(cpfNumero);

    if (!resultado.Valido)
    {
    var statusCode = resultado.Erro?.Contains("nao encontrado") == true
    ? HttpStatusCode.NotFound
    : HttpStatusCode.BadRequest;

    var errorResponse = req.CreateResponse(statusCode);
    await errorResponse.WriteAsJsonAsync(new { erro = resultado.Erro });
    return errorResponse;
    }

    var response = req.CreateResponse(HttpStatusCode.OK);
    await response.WriteAsJsonAsync(new
    {
    valido = true,
    dados = new
    {
    nome = resultado.Nome,
    genero = resultado.Genero,
    dataNascimento = resultado.DataNascimento
    }
    });

    return response;
    }
}

Configuração local

O arquivo local.settings.json para desenvolvimento:

{
    "IsEncrypted": false,
    "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
    "CPFHUB_API_KEY": "sua_chave_de_teste"
    }
}

Deploy para o Azure

Deploy usando Azure CLI:

# Criar recursos
az group create --name rg-cpf-validator --location brazilsouth
az storage account create --name stcpfvalidator --location brazilsouth \
    --resource-group rg-cpf-validator --sku Standard_LRS
az functionapp create --resource-group rg-cpf-validator \
    --consumption-plan-location brazilsouth \
    --runtime dotnet-isolated --runtime-version 8 \
    --functions-version 4 --name fn-cpf-validator \
    --storage-account stcpfvalidator

# Deploy do codigo
func azure functionapp publish fn-cpf-validator

A regiao brazilsouth garante a menor latência para usuários no Brasil.


Monitoramento com Application Insights

As Azure Functions enviam telemetria automaticamente para o Application Insights. Metricas úteis para monitorar:

  • Tempo de resposta -- Monitore o p95 para garantir que a combinação Function + API CPFHub.io se mantem abaixo de 2 segundos.
  • Taxa de falhas -- Configure alertas quando a taxa de erros ultrapassar 5%.
  • Dependências -- O Application Insights rastreia automaticamente chamadas HTTP externas, mostrando a latência da API da CPFHub.io separadamente.
  • Live Metrics -- Visualize requisições em tempo real durante testes de carga.

Perguntas frequentes

O que é necessário para integrar validação de CPF em Azure Functions com C#?

A integração requer um projeto .NET com o worker runtime dotnet-isolated, o pacote Microsoft.Azure.Functions.Worker.Extensions.Http e a chave de API da CPFHub.io configurada via Key Vault ou variável de ambiente. O HTTP trigger recebe o CPF via rota, e o HttpClient injetado faz a chamada GET para https://api.cpfhub.io/cpf/{CPF} com o header x-api-key.

Qual é a latência esperada ao usar a API CPFHub.io em uma Azure Function?

A API CPFHub.io tem latência média de ~900ms. Somado ao tempo de execução da Function, o tempo total de resposta costuma ficar entre 1 e 2 segundos. Configure o HttpClient.Timeout em pelo menos 10 segundos e monitore o p95 no Application Insights para identificar variações fora do esperado.

A API CPFHub.io retorna erro 429 quando o limite de consultas é atingido?

Não. A API não bloqueia nem retorna 429 ao atingir o limite do plano. Quando o volume mensal é ultrapassado, cada consulta adicional é cobrada a R$0,15. O plano gratuito inclui 50 consultas/mês; o plano Pro oferece 1.000 consultas por R$149/mês.

Como garantir conformidade com a LGPD ao consultar CPF em uma Azure Function?

Use o CPF apenas para a finalidade declarada ao titular, armazene apenas o necessário (não persista o número cru se um token interno bastar) e implemente controle de acesso aos logs do Application Insights. A ANPD orienta que dados de identificação devem ser tratados com o princípio da necessidade e finalidade.


Conclusão

Azure Functions com C# oferecem uma plataforma robusta para integrações com a API de CPF da CPFHub.io

Cadastre-se em cpfhub.io

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