# Como Integrar a API de CPF em uma Aplicação Go com Gin ou Echo

> Aprenda a integrar a API de CPF em aplicações Go usando os frameworks Gin e Echo, com middleware, validação e tratamento de erros.

**Publicado:** 01/09/2024
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/integrar-api-cpf-go-gin-echo

---


Para integrar a API de CPF da CPFHub.io em uma aplicação Go com Gin ou Echo, crie um cliente HTTP reutilizável com a chave `x-api-key` no header, encapsule a chamada em um middleware de validação e registre o handler no roteador do framework escolhido. Tanto Gin quanto Echo permitem essa integração em menos de 50 linhas de código, com suporte nativo a middleware, logging e tratamento de erros.

## Introdução

Gin e Echo são os dois frameworks web mais populares em Go, oferecendo roteamento rápido, middleware flexível e excelente performance. Integrar a API de CPF em uma aplicação construída com esses frameworks envolve criar handlers, middleware de validação e um cliente HTTP reutilizável.

---

## Comparação entre Gin e Echo

Ambos os frameworks são maduros e performáticos, com diferenças sutis na API.

| Característica | Gin | Echo |
|---|---|---|
| Performance | Excelente | Excelente |
| Popularidade (stars) | ~75k | ~28k |
| Middleware | Built-in + custom | Built-in + custom |
| Binding/Validação | JSON/XML/Form | JSON/XML/Form |
| Documentação | Extensa | Extensa |
| Context | `*gin.Context` | `echo.Context` |
| Resposta JSON | `c.JSON(code, obj)` | `c.JSON(code, obj)` |

---

## Implementação com Gin

A integração com Gin utiliza handlers e middleware para validação de CPF.

```go
package main

import (
 "encoding/json"
 "fmt"
 "net/http"
 "os"
 "regexp"
 "time"

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

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

type APIResponse struct {
 Success bool `json:"success"`
 Data 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"`
 } `json:"data"`
}

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

func (c *CPFHubClient) Consultar(cpf string) (*APIResponse, error) {
 url := fmt.Sprintf("%s/cpf/%s", c.baseURL, cpf)
 req, err := http.NewRequest("GET", url, nil)
 if err != nil {
 return nil, err
 }
 req.Header.Set("x-api-key", c.apiKey)

 resp, err := c.httpClient.Do(req)
 if err != nil {
 return nil, err
 }
 defer resp.Body.Close()

 var resultado APIResponse
 if err := json.NewDecoder(resp.Body).Decode(&resultado); err != nil {
 return nil, err
 }
 return &resultado, nil
}

// Middleware de validação de CPF para Gin
func ValidarCPFMiddleware() gin.HandlerFunc {
 re := regexp.MustCompile(`\D`)
 return func(c *gin.Context) {
 cpf := re.ReplaceAllString(c.Param("cpf"), "")
 if len(cpf) != 11 {
 c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
 "erro": "CPF deve conter 11 digitos",
 })
 return
 }
 c.Set("cpf_limpo", cpf)
 c.Next()
 }
}

func setupGinRouter(client *CPFHubClient) *gin.Engine {
 r := gin.Default()

 api := r.Group("/api")
 {
 cpf := api.Group("/cpf")
 cpf.Use(ValidarCPFMiddleware())
 {
 cpf.GET("/:cpf", func(c *gin.Context) {
 cpfLimpo := c.GetString("cpf_limpo")

 resultado, err := client.Consultar(cpfLimpo)
 if err != nil {
 c.JSON(http.StatusBadGateway, gin.H{
 "erro": "Falha ao consultar API externa",
 })
 return
 }

 if !resultado.Success {
 c.JSON(http.StatusNotFound, gin.H{
 "erro": "CPF nao encontrado",
 })
 return
 }

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

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

 return r
}

func main() {
 apiKey := os.Getenv("CPFHUB_API_KEY")
 client := NewCPFHubClient(apiKey)
 r := setupGinRouter(client)
 r.Run(":8080")
}
```

---

## Implementação com Echo

A mesma funcionalidade implementada usando o framework Echo.

```go
package main

import (
 "net/http"
 "os"
 "regexp"

 "github.com/labstack/echo/v4"
 "github.com/labstack/echo/v4/middleware"
)

// ValidarCPFMiddleware para Echo
func ValidarCPFMiddlewareEcho(next echo.HandlerFunc) echo.HandlerFunc {
 re := regexp.MustCompile(`\D`)
 return func(c echo.Context) error {
 cpf := re.ReplaceAllString(c.Param("cpf"), "")
 if len(cpf) != 11 {
 return c.JSON(http.StatusBadRequest, map[string]string{
 "erro": "CPF deve conter 11 digitos",
 })
 }
 c.Set("cpf_limpo", cpf)
 return next(c)
 }
}

func setupEchoRouter(client *CPFHubClient) *echo.Echo {
 e := echo.New()

 e.Use(middleware.Logger())
 e.Use(middleware.Recover())
 e.Use(middleware.CORS())

 api := e.Group("/api")

 cpfGroup := api.Group("/cpf")
 cpfGroup.Use(ValidarCPFMiddlewareEcho)

 cpfGroup.GET("/:cpf", func(c echo.Context) error {
 cpfLimpo := c.Get("cpf_limpo").(string)

 resultado, err := client.Consultar(cpfLimpo)
 if err != nil {
 return c.JSON(http.StatusBadGateway, map[string]string{
 "erro": "Falha ao consultar API externa",
 })
 }

 if !resultado.Success {
 return c.JSON(http.StatusNotFound, map[string]string{
 "erro": "CPF nao encontrado",
 })
 }

 return c.JSON(http.StatusOK, map[string]interface{}{
 "sucesso": true,
 "dados": resultado.Data,
 })
 })

 e.GET("/health", func(c echo.Context) error {
 return c.JSON(http.StatusOK, map[string]string{"status": "ok"})
 })

 return e
}

func main() {
 apiKey := os.Getenv("CPFHUB_API_KEY")
 client := NewCPFHubClient(apiKey)
 e := setupEchoRouter(client)
 e.Logger.Fatal(e.Start(":8080"))
}
```

---

## Middleware de rate limiting

Ambos os frameworks suportam middleware de rate limiting para proteger o serviço.

```go
// Rate limiting com Gin (usando gin-contrib)
import "github.com/gin-contrib/limiter"

// Rate limiting com Echo (built-in)
e.Use(middleware.RateLimiter(
 middleware.NewRateLimiterMemoryStore(20), // 20 req/s
))
```

| Configuração | Valor Recomendado | Framework |
|---|---|---|
| Rate limit global | 100 req/s | Gin e Echo |
| Rate limit por IP | 20 req/s | Gin e Echo |
| Timeout de requisição | 10 segundos | Ambos |
| Recovery middleware | Ativo | Ambos |
| CORS | Configurado | Ambos |
| Logger | Ativo | Ambos |

---

## Testes de integração

Escreva testes para garantir que os endpoints funcionam corretamente.

```go
package main

import (
 "net/http"
 "net/http/httptest"
 "testing"

 "github.com/stretchr/testify/assert"
)

func TestConsultarCPFGin(t *testing.T) {
 // Mock da API externa
 mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 w.Header().Set("Content-Type", "application/json")
 w.Write([]byte(`{
 "success": true,
 "data": {
 "cpf": "12345678901",
 "name": "Joao da Silva",
 "nameUpper": "JOAO DA SILVA",
 "gender": "M",
 "birthDate": "1990-01-15",
 "day": 15, "month": 1, "year": 1990
 }
 }`))
 }))
 defer mockServer.Close()

 client := &CPFHubClient{
 httpClient: mockServer.Client(),
 apiKey: "test-key",
 baseURL: mockServer.URL,
 }

 router := setupGinRouter(client)
 w := httptest.NewRecorder()
 req, _ := http.NewRequest("GET", "/api/cpf/12345678901", nil)
 router.ServeHTTP(w, req)

 assert.Equal(t, http.StatusOK, w.Code)
 assert.Contains(t, w.Body.String(), "Joao da Silva")
}

func TestCPFInvalidoGin(t *testing.T) {
 client := NewCPFHubClient("test-key")
 router := setupGinRouter(client)

 w := httptest.NewRecorder()
 req, _ := http.NewRequest("GET", "/api/cpf/123", nil)
 router.ServeHTTP(w, req)

 assert.Equal(t, http.StatusBadRequest, w.Code)
}
```

---

## Perguntas frequentes

### Qual a diferença prática entre usar Gin e Echo para integrar a API de CPF?
Ambos funcionam de forma equivalente para integrar a CPFHub.io. A principal diferença está na API de contexto: Gin usa `*gin.Context` com métodos como `c.GetString()`, enquanto Echo usa `echo.Context` com `c.Get()`. O middleware de validação de CPF segue o mesmo padrão nos dois frameworks — a escolha é de preferência da equipe.

### Como lidar com timeout na chamada à API de CPF em Go?
Configure `http.Client{Timeout: 10 * time.Second}` ao criar o cliente HTTP. Se o timeout for atingido, o erro `context deadline exceeded` é retornado e deve ser tratado no handler, retornando HTTP 504 ao cliente. A latência típica da CPFHub.io é de ~900ms, bem abaixo do limite de 10 segundos.

### É necessário validar o formato do CPF antes de chamar a API?
Sim. Remova caracteres não numéricos com uma regex `\D` e confirme que o resultado tem exatamente 11 dígitos antes de fazer a chamada. Isso evita requisições desnecessárias e garante respostas de erro claras para o cliente da sua API.

### Como reutilizar o cliente HTTP entre requisições em Go?
Instancie `CPFHubClient` uma única vez na inicialização da aplicação e injete-o nos handlers via closure ou dependência de roteador. O `http.Client` em Go é seguro para uso concorrente e reutilizar a mesma instância evita overhead de criação de conexão a cada requisição.

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

Integrar a API de CPF em aplicações Go com Gin ou Echo é direto e eficiente. Ambos os frameworks oferecem middleware flexível para validação, logging e rate limiting, tornando simples a criação de endpoints robustos para consulta de CPF. A escolha entre Gin e Echo depende da preferência da equipe, já que ambos entregam performance e funcionalidades equivalentes. A [documentação oficial do Go](https://pkg.go.dev/net/http) detalha as melhores práticas para clientes HTTP reutilizáveis em produção.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) — 50 consultas mensais gratuitas, sem cartão de crédito — e comece a integrar a API de CPF na sua aplicação Go hoje mesmo.

