Como integrar validação de CPF em microserviços Go com Gin framework

Aprenda a integrar a validação de CPF via API em microserviços Go usando Gin framework com exemplos completos, middleware e boas práticas.

Redação CPFHub.io
Redação CPFHub.io
··8 min de leitura
Como integrar validação de CPF em microserviços Go com Gin framework

Para integrar validação de CPF em um microserviço Go com Gin, crie um serviço dedicado que chama GET https://api.cpfhub.io/cpf/{CPF} com o header x-api-key, implemente um handler que expõe o resultado internamente e adicione middleware de rate limiting para controlar o consumo da cota mensal.

Introdução

O Gin é o framework web mais popular do ecossistema Go, conhecido pela sua performance excepcional e pela simplicidade de sua API. Em arquiteturas de microserviços, é comum ter um serviço dedicado à validação de identidade que consulta APIs externas para verificar dados cadastrais como o CPF.

Integrar a validação de CPF em um microserviço Go com Gin permite criar um ponto centralizado de verificação que pode ser consumido por outros serviços da arquitetura.

Pré-requisitos

  • Go 1.21+ — Instalado e configurado.
  • Conta na CPFHub.io — Para obter a chave de API (50 consultas/mês no plano gratuito, sem cartão).

Inicializando o projeto

mkdir cpf-service && cd cpf-service
go mod init cpf-service
go get github.com/gin-gonic/gin

Estrutura do projeto

cpf-service/
    main.go
    handlers/
    cpf_handler.go
    services/
    cpf_service.go
    models/
    cpf.go
    middleware/
    rate_limiter.go

Modelos de dados

// models/cpf.go
package models

type CpfResponse struct {
    Success bool `json:"success"`
    Data CpfData `json:"data"`
}

type CpfData struct {
    Cpf string `json:"cpf"`
    Name string `json:"name"`
    NameUpper string `json:"nameUpper"`
    Gender string `json:"gender"`
    BirthDate string `json:"birthDate"`
    Day int `json:"day"`
    Month int `json:"month"`
    Year int `json:"year"`
}

type ErrorResponse struct {
    Error string `json:"error"`
    Code int `json:"code"`
}

Serviço de consulta

// services/cpf_service.go
package services

import (
    "context"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "regexp"
    "time"

    "cpf-service/models"
)

type CpfService struct {
    httpClient *http.Client
    apiKey string
    baseURL string
}

func NewCpfService(apiKey string) *CpfService {
    return &CpfService{
    httpClient: &http.Client{
    Timeout: 10 * time.Second,
    },
    apiKey: apiKey,
    baseURL: "https://api.cpfhub.io",
    }
}

func (s *CpfService) Consultar(ctx context.Context, cpf string) (*models.CpfData, error) {
    re := regexp.MustCompile(`\D`)
    cpfLimpo := re.ReplaceAllString(cpf, "")

    if len(cpfLimpo) != 11 {
    return nil, fmt.Errorf("CPF inválido: informe 11 dígitos numéricos")
    }

    url := fmt.Sprintf("%s/cpf/%s", s.baseURL, cpfLimpo)

    req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
    if err != nil {
    return nil, fmt.Errorf("erro ao criar requisição: %w", err)
    }

    req.Header.Set("x-api-key", s.apiKey)
    req.Header.Set("Accept", "application/json")

    resp, err := s.httpClient.Do(req)
    if err != nil {
    if ctx.Err() == context.DeadlineExceeded {
    return nil, fmt.Errorf("tempo limite excedido")
    }
    return nil, fmt.Errorf("erro na requisição: %w", err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
    return nil, fmt.Errorf("erro ao ler resposta: %w", err)
    }

    if resp.StatusCode != http.StatusOK {
    return nil, fmt.Errorf("erro HTTP %d", resp.StatusCode)
    }

    var cpfResp models.CpfResponse
    if err := json.Unmarshal(body, &cpfResp); err != nil {
    return nil, fmt.Errorf("erro ao decodificar resposta: %w", err)
    }

    if !cpfResp.Success {
    return nil, fmt.Errorf("CPF não encontrado")
    }

    return &cpfResp.Data, nil
}

Handler HTTP

// handlers/cpf_handler.go
package handlers

import (
    "net/http"

    "cpf-service/models"
    "cpf-service/services"
    "github.com/gin-gonic/gin"
)

type CpfHandler struct {
    service *services.CpfService
}

func NewCpfHandler(service *services.CpfService) *CpfHandler {
    return &CpfHandler{service: service}
}

func (h *CpfHandler) Consultar(c *gin.Context) {
    cpf := c.Param("cpf")

    if cpf == "" {
    c.JSON(http.StatusBadRequest, models.ErrorResponse{
    Error: "CPF não informado.",
    Code: 400,
    })
    return
    }

    dados, err := h.service.Consultar(c.Request.Context(), cpf)
    if err != nil {
    status := http.StatusInternalServerError
    if err.Error() == "CPF inválido: informe 11 dígitos numéricos" {
    status = http.StatusBadRequest
    } else if err.Error() == "CPF não encontrado" {
    status = http.StatusNotFound
    } else if err.Error() == "tempo limite excedido" {
    status = http.StatusGatewayTimeout
    }

    c.JSON(status, models.ErrorResponse{
    Error: err.Error(),
    Code: status,
    })
    return
    }

    c.JSON(http.StatusOK, gin.H{
    "valido": true,
    "dados": dados,
    })
}

Middleware de rate limiting

Para proteger o microserviço de excesso de requisições internas e controlar o consumo da cota mensal da CPFHub.io:

// middleware/rate_limiter.go
package middleware

import (
    "net/http"
    "sync"
    "time"

    "github.com/gin-gonic/gin"
)

type RateLimiter struct {
    mu sync.Mutex
    lastCall time.Time
    interval time.Duration
}

func NewRateLimiter(interval time.Duration) *RateLimiter {
    return &RateLimiter{
    interval: interval,
    }
}

func (rl *RateLimiter) Middleware() gin.HandlerFunc {
    return func(c *gin.Context) {
    rl.mu.Lock()
    elapsed := time.Since(rl.lastCall)
    if elapsed < rl.interval {
    rl.mu.Unlock()
    c.JSON(http.StatusTooManyRequests, gin.H{
    "error": "Aguarde antes de realizar uma nova consulta.",
    })
    c.Abort()
    return
    }
    rl.lastCall = time.Now()
    rl.mu.Unlock()
    c.Next()
    }
}

Nota: esse rate limiting é aplicado pelo seu próprio microserviço para controlar o consumo interno da cota. A CPFHub.io não retorna HTTP 429 — ao exceder o limite mensal do plano, cada consulta extra é cobrada a R$0,15 sem interrupção do serviço.

Montando o servidor principal

// main.go
package main

import (
    "log"
    "os"
    "time"

    "cpf-service/handlers"
    "cpf-service/middleware"
    "cpf-service/services"
    "github.com/gin-gonic/gin"
)

func main() {
    apiKey := os.Getenv("CPFHUB_API_KEY")
    if apiKey == "" {
    apiKey = "SUA_CHAVE_DE_API"
    }

    cpfService := services.NewCpfService(apiKey)
    cpfHandler := handlers.NewCpfHandler(cpfService)
    rateLimiter := middleware.NewRateLimiter(2 * time.Second)

    r := gin.Default()

    api := r.Group("/api")
    {
    cpf := api.Group("/cpf")
    cpf.Use(rateLimiter.Middleware())
    {
    cpf.GET("/:cpf", cpfHandler.Consultar)
    }
    }

    r.GET("/health", func(c *gin.Context) {
    c.JSON(200, gin.H{"status": "ok"})
    })

    log.Println("Servidor iniciado na porta 8080")
    if err := r.Run(":8080"); err != nil {
    log.Fatalf("Erro ao iniciar servidor: %v", err)
    }
}

Testando o microserviço

# Iniciar o servidor
CPFHUB_API_KEY=SUA_CHAVE_DE_API go run main.go

# Em outro terminal, consultar CPF
curl -X GET http://localhost:8080/api/cpf/12345678900 \
    -H "Accept: application/json" \
    --max-time 10

Para testar diretamente a API da CPFHub.io:

curl -X GET https://api.cpfhub.io/cpf/12345678900 \
    -H "x-api-key: SUA_CHAVE_DE_API" \
    -H "Accept: application/json" \
    --max-time 10

Boas práticas para microserviços

  • Health check — Inclua um endpoint /health para monitoramento e orquestração (Kubernetes, Docker Swarm).

  • Context propagation — Propague o context do Gin para o serviço para garantir cancelamento e timeout corretos.

  • Variáveis de ambiente — Armazene segredos em variáveis de ambiente, nunca no código.

  • Controle de consumo — Implemente rate limiting interno para não exceder a cota mensal do plano sem necessidade. O plano gratuito da CPFHub.io inclui 50 consultas/mês; o plano Pro oferece 1.000 por R$149/mês, com excedente a R$0,15.

  • Observabilidade — Adicione métricas (Prometheus), traces (OpenTelemetry) e logs estruturados para monitoramento em produção.

Perguntas frequentes

Por que centralizar a validação de CPF em um microserviço dedicado?

Um microserviço de validação evita que múltiplos serviços da arquitetura façam chamadas independentes à API externa, o que dispersa o controle de cotas, dificulta o monitoramento e aumenta a chance de falhas silenciosas. Com um ponto central, você aplica cache, rate limiting, logging e circuit breaker em um único lugar — qualquer mudança de provedor ou atualização de API key afeta apenas esse serviço.

Como implementar circuit breaker para proteger o microserviço de falhas na API externa?

A biblioteca sony/gobreaker é uma opção madura para Go. Configure o circuit breaker para abrir após um número configurável de falhas consecutivas (ex: 5), aguardar um intervalo de recuperação (ex: 30 segundos) e testar com uma requisição de prova antes de fechar. Durante o estado aberto, o serviço deve retornar o resultado do cache ou sinalizar degradação graceful em vez de propagar o erro.

O campo nameUpper da resposta da CPFHub.io é diferente de name?

Sim. O campo name retorna o nome com capitalização mista (ex: "João da Silva"), enquanto nameUpper retorna tudo em maiúsculas (ex: "JOÃO DA SILVA"). Para comparações de nome — como verificar divergências em cadastros — prefira usar nameUpper após converter o nome informado pelo usuário para maiúsculas, evitando falsos positivos por diferença de capitalização.

Como lidar com o timeout de ~900ms da API em contextos de alta concorrência?

Configure o http.Client com Timeout de 10 segundos para acomodar variações de latência. Em cenários de alta concorrência, implemente cache Redis com TTL de 24 horas para CPFs já consultados — a maioria das requisições será atendida localmente em menos de 1ms. Para picos previsíveis (ex: campanhas de cadastro), pré-aqueça o cache consultando os CPFs do público-alvo fora do horário de pico.


Conclusão

Construir um microserviço de validação de CPF com Go e Gin é uma abordagem eficiente que centraliza a lógica de verificação e pode ser consumida por toda a arquitetura de microserviços. Com cache, rate limiting interno e observabilidade, o serviço fica robusto para produção desde o primeiro deploy.

Cadastre-se em cpfhub.io — 50 consultas mensais gratuitas, sem cartão de crédito — e integre a validação de CPF ao seu microserviço Go em menos de 30 minutos usando os exemplos deste guia.

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