Como Criar um CLI de Consulta de CPF em Go com Cobra

Aprenda a criar uma ferramenta de linha de comando para consultar CPFs em Go usando Cobra, com subcomandos, flags, output formatado e autocomplete.

Redação CPFHub.io
Redação CPFHub.io
··8 min de leitura
Como Criar um CLI de Consulta de CPF em Go com Cobra

Para criar um CLI de consulta de CPF em Go com Cobra, estruture o projeto com subcomandos separados para consulta via API, validação algorítmica local e processamento em lote — compilando para um binário estático distribuível em Linux, macOS e Windows. A biblioteca Cobra, a mesma usada no kubectl e no Docker CLI, oferece flags globais, autocomplete e output em múltiplos formatos com poucas linhas de configuração.

Introdução

Ferramentas de linha de comando (CLI) são essenciais para automação, scripts e operações de suporte. Uma CLI de consulta de CPF permite que desenvolvedores e analistas consultem CPFs rapidamente sem precisar de interfaces gráficas ou chamadas manuais à API. O Cobra é a biblioteca mais utilizada para construir CLIs em Go, sendo a mesma usada no kubectl, Docker CLI e Hugo.


Estrutura do projeto

A estrutura segue o padrão recomendado pelo Cobra para projetos CLI.

// Estrutura de diretórios
// cpf-cli/
// cmd/
// root.go
// consultar.go
// lote.go
// validar.go
// internal/
// client/
// cpfhub.go
// formatter/
// output.go
// main.go
// go.mod
ArquivoResponsabilidade
main.goPonto de entrada
cmd/root.goComando raiz e flags globais
cmd/consultar.goSubcomando para consulta individual
cmd/lote.goSubcomando para consulta em lote
cmd/validar.goSubcomando para validação algorítmica
internal/clientCliente HTTP para a API
internal/formatterFormatação de output

Comando raiz e configuração

O comando raiz define as flags globais e a estrutura base da CLI.

// main.go
package main

import "cpf-cli/cmd"

func main() {
    cmd.Execute()
}

// cmd/root.go
package cmd

import (
    "fmt"
    "os"

    "github.com/spf13/cobra"
)

var (
    apiKey string
    outputFormat string
)

var rootCmd = &cobra.Command{
    Use: "cpf-cli",
    Short: "Ferramenta de linha de comando para consulta de CPF",
    Long: `cpf-cli permite consultar e validar CPFs via API do CPFHub.
Suporta consultas individuais, em lote e validação algoritmica local.`,
}

func Execute() {
    if err := rootCmd.Execute(); err != nil {
    fmt.Fprintln(os.Stderr, err)
    os.Exit(1)
    }
}

func init() {
    rootCmd.PersistentFlags().StringVar(
    &apiKey, "api-key", "",
    "Chave da API do CPFHub (ou CPFHUB_API_KEY)",
    )
    rootCmd.PersistentFlags().StringVarP(
    &outputFormat, "output", "o", "table",
    "Formato de saida: table, json, csv",
    )
}

func getAPIKey() string {
    if apiKey != "" {
    return apiKey
    }
    return os.Getenv("CPFHUB_API_KEY")
}

Subcomando de consulta individual

O subcomando consultar faz a consulta de um CPF específico via API.

// cmd/consultar.go
package cmd

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

    "github.com/spf13/cobra"
)

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"`
}

var consultarCmd = &cobra.Command{
    Use: "consultar [cpf]",
    Short: "Consulta um CPF via API do CPFHub",
    Args: cobra.ExactArgs(1),
    Example: " cpf-cli consultar 123.456.789-01\n cpf-cli consultar 12345678901 -o json",
    RunE: func(cmd *cobra.Command, args []string) error {
    key := getAPIKey()
    if key == "" {
    return fmt.Errorf("API key nao configurada. Use --api-key ou CPFHUB_API_KEY")
    }

    re := regexp.MustCompile(`\D`)
    cpf := re.ReplaceAllString(args[0], "")

    if len(cpf) != 11 {
    return fmt.Errorf("CPF deve conter 11 digitos, recebido: %d", len(cpf))
    }

    resultado, err := consultarAPI(cpf, key)
    if err != nil {
    return fmt.Errorf("erro ao consultar API: %w", err)
    }

    return exibirResultado(resultado)
    },
}

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

    client := &http.Client{Timeout: 10 * time.Second}
    resp, err := client.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
}

func exibirResultado(resultado *APIResponse) error {
    if !resultado.Success {
    fmt.Println("CPF nao encontrado na base de dados.")
    return nil
    }

    switch outputFormat {
    case "json":
    enc := json.NewEncoder(os.Stdout)
    enc.SetIndent("", " ")
    return enc.Encode(resultado.Data)
    case "csv":
    fmt.Printf("cpf,nome,genero,nascimento\n")
    fmt.Printf("%s,%s,%s,%s\n",
    resultado.Data.CPF,
    resultado.Data.Name,
    resultado.Data.Gender,
    resultado.Data.BirthDate,
    )
    default: // table
    w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
    fmt.Fprintln(w, "CAMPO\tVALOR")
    fmt.Fprintln(w, "-----\t-----")
    fmt.Fprintf(w, "CPF\t%s\n", resultado.Data.CPF)
    fmt.Fprintf(w, "Nome\t%s\n", resultado.Data.Name)
    fmt.Fprintf(w, "Genero\t%s\n", resultado.Data.Gender)
    fmt.Fprintf(w, "Nascimento\t%s\n", resultado.Data.BirthDate)
    w.Flush()
    }
    return nil
}

func init() {
    rootCmd.AddCommand(consultarCmd)
}

Subcomando de validação local

O subcomando validar verifica o CPF algoritmicamente sem chamar a API.

// cmd/validar.go
package cmd

import (
    "fmt"
    "regexp"
    "strconv"

    "github.com/spf13/cobra"
)

var validarCmd = &cobra.Command{
    Use: "validar [cpf]",
    Short: "Valida um CPF algoritmicamente (sem consultar API)",
    Args: cobra.ExactArgs(1),
    Example: " cpf-cli validar 123.456.789-01",
    Run: func(cmd *cobra.Command, args []string) {
    re := regexp.MustCompile(`\D`)
    cpf := re.ReplaceAllString(args[0], "")

    if len(cpf) != 11 {
    fmt.Printf("INVALIDO: CPF deve conter 11 digitos (recebido %d)\n", len(cpf))
    return
    }

    if validarDigitosCPF(cpf) {
    fmt.Printf("VALIDO: CPF %s possui digitos verificadores corretos\n", formatarCPF(cpf))
    } else {
    fmt.Printf("INVALIDO: CPF %s possui digitos verificadores incorretos\n", formatarCPF(cpf))
    }
    },
}

func validarDigitosCPF(cpf string) bool {
    todosIguais := true
    for i := 1; i < 11; i++ {
    if cpf[i] != cpf[0] {
    todosIguais = false
    break
    }
    }
    if todosIguais {
    return false
    }

    soma := 0
    for i := 0; i < 9; i++ {
    d, _ := strconv.Atoi(string(cpf[i]))
    soma += d * (10 - i)
    }
    resto := (soma * 10) % 11
    if resto == 10 {
    resto = 0
    }
    d9, _ := strconv.Atoi(string(cpf[9]))
    if resto != d9 {
    return false
    }

    soma = 0
    for i := 0; i < 10; i++ {
    d, _ := strconv.Atoi(string(cpf[i]))
    soma += d * (11 - i)
    }
    resto = (soma * 10) % 11
    if resto == 10 {
    resto = 0
    }
    d10, _ := strconv.Atoi(string(cpf[10]))
    return resto == d10
}

func formatarCPF(cpf string) string {
    return fmt.Sprintf("%s.%s.%s-%s", cpf[0:3], cpf[3:6], cpf[6:9], cpf[9:11])
}

func init() {
    rootCmd.AddCommand(validarCmd)
}
SubcomandoUsoRequer API Key
consultarConsulta CPF via APISim
validarValidação algorítmica localNão
loteConsulta múltiplos CPFsSim

Build e distribuição

Compile a CLI para múltiplas plataformas usando o sistema de build do Go.

// Makefile
// build:
// GOOS=linux GOARCH=amd64 go build -o bin/cpf-cli-linux-amd64 .
// GOOS=darwin GOARCH=amd64 go build -o bin/cpf-cli-darwin-amd64 .
// GOOS=darwin GOARCH=arm64 go build -o bin/cpf-cli-darwin-arm64 .
// GOOS=windows GOARCH=amd64 go build -o bin/cpf-cli-windows-amd64.exe .
PlataformaBinárioTamanho Aproximado
Linux AMD64cpf-cli-linux-amd64~8MB
macOS AMD64cpf-cli-darwin-amd64~8MB
macOS ARM64cpf-cli-darwin-arm64~8MB
Windows AMD64cpf-cli-windows-amd64.exe~8MB

Perguntas frequentes

Quais dependências externas são necessárias para construir o CLI?

O projeto depende de duas bibliotecas: github.com/spf13/cobra para a estrutura do CLI e a biblioteca padrão do Go para as chamadas HTTP. Não há dependências de terceiros para networking — o net/http nativo do Go é suficiente para consumir a API da CPFHub.io com timeout configurável.

A CLI funciona sem conexão à internet?

O subcomando validar funciona completamente offline, pois executa apenas a validação algorítmica dos dígitos verificadores do CPF. Já o subcomando consultar requer conexão com a internet para acessar https://api.cpfhub.io/cpf/{CPF} e retornar nome, gênero e data de nascimento do titular.

Como distribuir a CLI para uma equipe sem Go instalado?

O Go compila para binários estáticos sem dependências de runtime. Basta compilar para cada plataforma alvo (GOOS/GOARCH) e distribuir o executável diretamente — sem precisar instalar Go, Docker ou qualquer runtime adicional nas máquinas dos usuários.

Como proteger a chave de API ao usar a CLI em scripts de CI/CD?

Prefira a variável de ambiente CPFHUB_API_KEY em vez da flag --api-key para evitar que a chave apareça nos logs do terminal. Em pipelines de CI, use secrets gerenciados pela plataforma (GitHub Actions Secrets, GitLab CI Variables etc.) e injete como variável de ambiente. Consulte as boas práticas de segurança da OWASP para proteção de credenciais em APIs.


Conclusão

Uma CLI de consulta de CPF construída com Go e Cobra é uma ferramenta poderosa para desenvolvedores, analistas e equipes de suporte. Com subcomandos claros, múltiplos formatos de saída e distribuição como binário estático, a ferramenta é portável e fácil de integrar em scripts de automação. A validação algorítmica local funciona sem API, enquanto a consulta via API retorna dados completos do titular.

Cadastre-se em cpfhub.io — 50 consultas mensais gratuitas, sem cartão de crédito — e comece a construir sua CLI de consulta de CPF com dados reais hoje mesmo.

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