Cliente HTTP em Go: fazendo requisições corretamente de A a Z

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: Por que é importante saber trabalhar com HTTP em Go

\n

Go (Golang) é uma linguagem criada para trabalhar em rede. Sua biblioteca padrão net/http fornece ferramentas poderosas e flexíveis para criar tanto servidores quanto clientes. No entanto, muitos desenvolvedores, especialmente os vindos de linguagens de script, cometem erros típicos: esquecem de fechar o corpo da resposta, não configuram timeouts ou tratam erros incorretamente.

\n

Neste artigo, vamos abordar a criação de um cliente HTTP em Go "de A a Z". Você aprenderá como enviar requisições GET e POST corretamente, gerenciar cabeçalhos, configurar timeouts e tratar erros. Todos os exemplos de código estão prontos para uso.

\n\n

1. Fundamentos: criando um cliente e a primeira requisição GET

\n

Em Go, o cliente HTTP é uma estrutura http.Client. Você pode usar o cliente global http.DefaultClient ou criar o seu próprio com configurações personalizadas. Vamos começar com uma requisição GET simples.

\n
package main\n\nimport (\n    "fmt"\n    "io"\n    "net/http"\n    "os"\n)\n\nfunc main() {\n    // Usando o cliente embutido\n    resp, err := http.Get("https://api.example.com/data")\n    if err != nil {\n        fmt.Printf("Erro na requisição: %v\\n", err)\n        os.Exit(1)\n    }\n    defer resp.Body.Close() // IMPORTANTE: sempre fechar o corpo da resposta!\n\n    // Lendo o corpo da resposta\n    body, err := io.ReadAll(resp.Body)\n    if err != nil {\n        fmt.Printf("Erro ao ler a resposta: %v\\n", err)\n        os.Exit(1)\n    }\n\n    fmt.Printf("Status: %s\\n", resp.Status)\n    fmt.Printf("Corpo: %s\\n", string(body))\n}
\n

Pontos-chave:

\n
    \n
  • Sempre feche resp.Body usando defer. Caso contrário, ocorrerá vazamento de recursos (as conexões não retornarão ao pool).
  • \n
  • Verifique o status da resposta (resp.StatusCode). O código 200 não é o único de sucesso (existem 201, 204, etc.).
  • \n
  • io.ReadAll lê todo o corpo para a memória. Para respostas grandes, use io.Copy ou processamento em fluxo.
  • \n
\n\n

2. Cliente avançado: timeouts, cabeçalhos e configurações personalizadas

\n

O cliente global não possui timeouts por padrão — isso pode fazer o programa travar. Sempre crie seu próprio cliente com configurações.

\n

2.1. Criando um cliente com timeout

\n
client := &http.Client{\n    Timeout: 10 * time.Second, // Timeout total para toda a requisição\n}\n\nresp, err := client.Get("https://api.example.com/data")
\n

Você também pode configurar timeouts em diferentes níveis através do Transport:

\n
transport := &http.Transport{\n    DialContext: (&net.Dialer{\n        Timeout:   5 * time.Second, // Timeout de conexão\n        KeepAlive: 30 * time.Second,\n    }).DialContext,\n    TLSHandshakeTimeout:   5 * time.Second,\n    ResponseHeaderTimeout: 5 * time.Second,\n}\n\nclient := &http.Client{\n    Transport: transport,\n    Timeout:   15 * time.Second,\n}
\n\n

2.2. Adicionando cabeçalhos e parâmetros

\n

Para requisições complexas, use http.NewRequest:

\n
req, err := http.NewRequest("GET", "https://api.example.com/search", nil)\nif err != nil {\n    log.Fatal(err)\n}\n\n// Adicionando cabeçalhos\nreq.Header.Set("Authorization", "Bearer your-token")\nreq.Header.Set("Accept", "application/json")\n\n// Adicionando parâmetros de consulta\nq := req.URL.Query()\nq.Add("query", "golang")\nq.Add("page", "1")\nreq.URL.RawQuery = q.Encode()\n\nresp, err := client.Do(req)
\n\n

3. Trabalhando com POST e outros métodos (JSON, formulários)

\n

Requisições POST exigem o envio de um corpo. Vamos considerar dois formatos populares: JSON e formulário URL-encoded.

\n

3.1. POST com JSON

\n
type RequestData struct {\n    Name  string `json:"name"`\n    Email string `json:"email"`\n}\n\ndata := RequestData{\n    Name:  "João",\n    Email: "joao@example.com",\n}\n\njsonData, err := json.Marshal(da                

Blogs

Book Recommendations