---
title: "Zig HTTP GET: buscar APIs com std.http.Client"
url: "https://ziglang.com.br/receitas/zig-http-get-request/"
markdown_url: "https://ziglang.com.br/receitas/zig-http-get-request.MD"
description: "Receita prática de Zig HTTP GET com std.http.Client: headers, JSON, limite de resposta, validação de status e links para APIs REST em Zig."
date: "2026-02-21"
author: "Zig Brasil"
---

# Zig HTTP GET: buscar APIs com std.http.Client

Receita prática de Zig HTTP GET com std.http.Client: headers, JSON, limite de resposta, validação de status e links para APIs REST em Zig.


## Introdução

Requisições HTTP GET são a forma mais comum de buscar dados da web. Em Zig, a biblioteca padrão oferece `std.http.Client` para fazer requisições HTTP com controle explícito sobre headers, alocação, limite de resposta e tratamento de status.

Nesta receita, você aprenderá a fazer **HTTP GET em Zig**, processar respostas, lidar com headers e consumir APIs REST em JSON. Se você quer o guia completo de cliente HTTP, leia [Zig HTTP Client: GET, POST, JSON e APIs REST em Zig](/tutoriais/zig-http-client/). Se o objetivo é receber chamadas em um serviço próprio, combine com [Zig Server HTTP: API REST com std.http.Server](/tutoriais/zig-http-server/).

## Resposta rápida: GET em Zig com std.http.Client

| Objetivo | Caminho em Zig | Próximo link |
|---|---|---|
| Fazer um GET simples | `client.open(.GET, uri, ...)`, `send()`, `wait()` e leitura com limite | Continue nesta receita |
| Consumir JSON de uma API REST | Validar `req.status`, limitar `readAllAlloc` e parsear com `std.json` | [Parsing JSON em Zig](/tutoriais/parsing-json-zig/) |
| Enviar dados depois do GET | Usar `.POST`, `Content-Type: application/json` e `content_length` | [Zig HTTP POST: enviar JSON e formulários](/receitas/zig-http-post-request/) |
| Entender a API completa | `std.http.Client.fetch`, headers, TLS, redirects e storage da resposta | [std.http.Client em Zig](/stdlib/std-http-client/) |
| Criar a API que responde | `std.http.Server`, rotas, JSON e status explícitos | [Zig Server HTTP: API REST com std.http.Server](/tutoriais/zig-http-server/) |

O fluxo mínimo é sempre o mesmo: parsear a URL, abrir a requisição com método `.GET`, enviar a requisição, aguardar a resposta, validar o status e só então ler o corpo com um limite conhecido. Para integrações em produção, defina `User-Agent`, diferencie erro de rede de erro HTTP e registre contexto suficiente para depuração sem gravar tokens.

## Pré-requisitos

- Zig instalado (versão 0.13+). Veja o [guia de instalação](/tutoriais/como-instalar-zig/)
- Conhecimento básico de Zig. Consulte a [introdução ao Zig](/tutoriais/introducao-ao-zig/)
- Familiaridade com JSON quando a API retornar objetos. Consulte [Parsing JSON em Zig](/tutoriais/parsing-json-zig/) para o guia completo.

## Requisição GET simples

O exemplo mais básico de uma requisição HTTP GET:

```zig
const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // Criar cliente HTTP
    var client = std.http.Client{ .allocator = allocator };
    defer client.deinit();

    // Fazer a requisição GET
    const uri = try std.Uri.parse("http://httpbin.org/get");

    var header_buf: [4096]u8 = undefined;
    var req = try client.open(.GET, uri, .{
        .server_header_buffer = &header_buf,
    });
    defer req.deinit();

    try req.send();
    try req.wait();

    // Verificar status
    if (req.status != .ok) {
        std.debug.print("Erro HTTP: {}\n", .{req.status});
        return;
    }

    // Ler o corpo da resposta
    var body = std.ArrayList(u8).init(allocator);
    defer body.deinit();

    var buf: [4096]u8 = undefined;
    while (true) {
        const bytes_read = try req.reader().read(&buf);
        if (bytes_read == 0) break;
        try body.appendSlice(buf[0..bytes_read]);
    }

    std.debug.print("Status: {}\n", .{req.status});
    std.debug.print("Corpo: {s}\n", .{body.items});
}
```

### Saída esperada

```
Status: http.Status.ok
Corpo: {
  "args": {},
  "headers": {
    "Host": "httpbin.org",
    ...
  },
  "url": "http://httpbin.org/get"
}
```

## GET com headers customizados

Adicione headers personalizados à requisição:

```zig
const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    var client = std.http.Client{ .allocator = allocator };
    defer client.deinit();

    const uri = try std.Uri.parse("https://api.example.com/data");

    var header_buf: [4096]u8 = undefined;
    var req = try client.open(.GET, uri, .{
        .server_header_buffer = &header_buf,
        .extra_headers = &.{
            .{ .name = "Authorization", .value = "Bearer meu-token-aqui" },
            .{ .name = "Accept", .value = "application/json" },
            .{ .name = "User-Agent", .value = "ZigClient/1.0" },
        },
    });
    defer req.deinit();

    try req.send();
    try req.wait();

    std.debug.print("Status: {}\n", .{req.status});
}
```

## Função reutilizável de GET

Encapsule a lógica em uma função para reutilização:

```zig
const std = @import("std");

const HttpResponse = struct {
    status: std.http.Status,
    body: []const u8,
    allocator: std.mem.Allocator,

    pub fn deinit(self: *HttpResponse) void {
        self.allocator.free(self.body);
    }
};

fn httpGet(allocator: std.mem.Allocator, url: []const u8) !HttpResponse {
    var client = std.http.Client{ .allocator = allocator };
    defer client.deinit();

    const uri = try std.Uri.parse(url);

    var header_buf: [8192]u8 = undefined;
    var req = try client.open(.GET, uri, .{
        .server_header_buffer = &header_buf,
    });
    defer req.deinit();

    try req.send();
    try req.wait();

    // Ler corpo completo
    const body = try req.reader().readAllAlloc(allocator, 1024 * 1024); // máx 1 MB

    return .{
        .status = req.status,
        .body = body,
        .allocator = allocator,
    };
}

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // Usar a função reutilizável
    var response = try httpGet(allocator, "http://httpbin.org/get");
    defer response.deinit();

    std.debug.print("Status: {}\n", .{response.status});
    std.debug.print("Tamanho do corpo: {d} bytes\n", .{response.body.len});
}
```

## Consumindo uma API REST com JSON

Combine HTTP GET com parsing JSON para consumir APIs:

```zig
const std = @import("std");

const Todo = struct {
    userId: i64,
    id: i64,
    title: []const u8,
    completed: bool,
};

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    var client = std.http.Client{ .allocator = allocator };
    defer client.deinit();

    const uri = try std.Uri.parse("https://jsonplaceholder.typicode.com/todos/1");

    var header_buf: [4096]u8 = undefined;
    var req = try client.open(.GET, uri, .{
        .server_header_buffer = &header_buf,
    });
    defer req.deinit();

    try req.send();
    try req.wait();

    if (req.status != .ok) {
        std.debug.print("Erro: {}\n", .{req.status});
        return;
    }

    // Ler corpo
    const body = try req.reader().readAllAlloc(allocator, 1024 * 1024);
    defer allocator.free(body);

    // Parsear JSON
    const parsed = try std.json.parseFromSlice(Todo, allocator, body, .{
        .ignore_unknown_fields = true,
    });
    defer parsed.deinit();

    const todo = parsed.value;
    std.debug.print("Todo #{d}:\n", .{todo.id});
    std.debug.print("  Título: {s}\n", .{todo.title});
    std.debug.print("  Completo: {}\n", .{todo.completed});
    std.debug.print("  Usuário: {d}\n", .{todo.userId});
}
```

### Saída esperada

```
Todo #1:
  Título: delectus aut autem
  Completo: false
  Usuário: 1
```

## Tratamento de erros HTTP

Trate diferentes códigos de status HTTP adequadamente:

```zig
const std = @import("std");

fn handleHttpResponse(status: std.http.Status) void {
    switch (status) {
        .ok => std.debug.print("Sucesso (200)!\n", .{}),
        .not_found => std.debug.print("Recurso não encontrado (404).\n", .{}),
        .unauthorized => std.debug.print("Não autorizado (401). Verifique suas credenciais.\n", .{}),
        .forbidden => std.debug.print("Acesso proibido (403).\n", .{}),
        .internal_server_error => std.debug.print("Erro interno do servidor (500).\n", .{}),
        .too_many_requests => std.debug.print("Muitas requisições (429). Aguarde.\n", .{}),
        else => std.debug.print("Status inesperado: {d}\n", .{@intFromEnum(status)}),
    }
}

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    var client = std.http.Client{ .allocator = allocator };
    defer client.deinit();

    const uri = try std.Uri.parse("http://httpbin.org/status/404");

    var header_buf: [4096]u8 = undefined;
    var req = try client.open(.GET, uri, .{
        .server_header_buffer = &header_buf,
    });
    defer req.deinit();

    try req.send();
    try req.wait();

    handleHttpResponse(req.status);
}
```

## Dicas e boas práticas

1. **Sempre libere recursos**: Use `defer` para `client.deinit()` e `req.deinit()`.

2. **Verifique o status**: Nem toda resposta é `200 OK`. Sempre verifique o código de status.

3. **Limite o tamanho da resposta**: Use `readAllAlloc` com um limite máximo para evitar uso excessivo de memória.

4. **Reutilize o client**: Se fizer múltiplas requisições, reutilize a instância de `std.http.Client`.

5. **Para JSON**: Combine com [Parsing JSON em Zig](/tutoriais/parsing-json-zig/) para APIs REST completas ou com a [receita de parsear JSON](/receitas/zig-parse-json/) para exemplos curtos.

## Receitas relacionadas

- [Zig HTTP POST: enviar JSON e formulários com std.http.Client](/receitas/zig-http-post-request/) - Envio de dados
- [Como parsear JSON em Zig](/receitas/zig-parse-json/) - Processar respostas JSON
- [Como parsear URLs em Zig](/receitas/zig-parse-url/) - Manipulação de URLs
- [Como fazer lookup DNS em Zig](/receitas/zig-dns-lookup/) - Resolução de nomes

## Tutoriais relacionados

- [Zig HTTP Client: GET, POST, JSON e APIs REST em Zig](/tutoriais/zig-http-client/)
- [Zig Server HTTP: API REST com std.http.Server](/tutoriais/zig-http-server/)
- [Parsing JSON em Zig](/tutoriais/parsing-json-zig/)
