---
title: "Clientes HTTP em Zig — Requisições, TLS e APIs REST"
url: "https://ziglang.com.br/ecossistema/clientes-http-em-zig-requisi%C3%A7%C3%B5es-tls-e-apis-rest/"
markdown_url: "https://ziglang.com.br/ecossistema/clientes-http-em-zig-requisi%C3%A7%C3%B5es-tls-e-apis-rest.MD"
description: "Guia dos clientes HTTP em Zig: std.http.Client, requisições GET/POST, TLS, headers, parsing de respostas, servidores HTTP e consumo de APIs REST."
date: "2026-02-21"
author: "Zig Brasil"
---

# Clientes HTTP em Zig — Requisições, TLS e APIs REST

Guia dos clientes HTTP em Zig: std.http.Client, requisições GET/POST, TLS, headers, parsing de respostas, servidores HTTP e consumo de APIs REST.


# Clientes HTTP em Zig — Requisições, TLS e APIs REST

O consumo de APIs e serviços web é uma necessidade fundamental em aplicações modernas. O Zig oferece um cliente HTTP robusto na biblioteca padrão (`std.http.Client`) com suporte a TLS, além de bibliotecas de terceiros para cenários especializados. Este guia cobre desde requisições básicas até padrões avançados para consumo de APIs REST.

## std.http.Client — O Cliente Padrão

A biblioteca padrão inclui um cliente HTTP completo com suporte a HTTP/1.1, TLS 1.3, redirects e conexões keep-alive:

### GET Simples

```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();

    // Requisição GET
    const uri = try std.Uri.parse("https://api.exemplo.com/dados");

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

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

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

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

### POST com JSON

```zig
pub fn postJson(allocator: std.mem.Allocator, url: []const u8, payload: []const u8) ![]u8 {
    var client = std.http.Client{ .allocator = allocator };
    defer client.deinit();

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

    var buf: [8192]u8 = undefined;
    var req = try client.open(.POST, uri, .{
        .server_header_buffer = &buf,
        .extra_headers = &.{
            .{ .name = "Content-Type", .value = "application/json" },
            .{ .name = "Accept", .value = "application/json" },
        },
    });
    defer req.deinit();

    req.transfer_encoding = .{ .content_length = payload.len };
    try req.send();
    try req.writer().writeAll(payload);
    try req.finish();
    try req.wait();

    if (req.status != .ok and req.status != .created) {
        return error.HttpError;
    }

    return try req.reader().readAllAlloc(allocator, 1024 * 1024);
}

// Uso
pub fn criarUsuario(allocator: std.mem.Allocator) !void {
    const payload =
        \\{"nome": "Maria Silva", "email": "maria@exemplo.com"}
    ;

    const resposta = try postJson(
        allocator,
        "https://api.exemplo.com/usuarios",
        payload,
    );
    defer allocator.free(resposta);

    std.debug.print("Resposta: {s}\n", .{resposta});
}
```

### Headers de Autenticação

```zig
pub fn getComAuth(allocator: std.mem.Allocator, url: []const u8, token: []const u8) ![]u8 {
    var client = std.http.Client{ .allocator = allocator };
    defer client.deinit();

    var auth_header_buf: [256]u8 = undefined;
    const auth_value = try std.fmt.bufPrint(&auth_header_buf, "Bearer {s}", .{token});

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

    var buf: [8192]u8 = undefined;
    var req = try client.open(.GET, uri, .{
        .server_header_buffer = &buf,
        .extra_headers = &.{
            .{ .name = "Authorization", .value = auth_value },
        },
    });
    defer req.deinit();

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

    return try req.reader().readAllAlloc(allocator, 1024 * 1024);
}
```

## Cliente HTTP com Tipagem Forte

Construindo um wrapper tipado para APIs:

```zig
fn ApiClient(comptime base_url: []const u8) type {
    return struct {
        allocator: std.mem.Allocator,
        token: ?[]const u8 = null,

        const Self = @This();

        pub fn init(allocator: std.mem.Allocator) Self {
            return .{ .allocator = allocator };
        }

        pub fn comAuth(self: *Self, token: []const u8) *Self {
            self.token = token;
            return self;
        }

        pub fn get(self: *Self, comptime T: type, path: []const u8) !T {
            var url_buf: [512]u8 = undefined;
            const url = try std.fmt.bufPrint(&url_buf, "{s}{s}", .{ base_url, path });

            var client = std.http.Client{ .allocator = self.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();

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

            const parsed = try std.json.parseFromSlice(T, self.allocator, body, .{
                .ignore_unknown_fields = true,
            });
            return parsed.value;
        }
    };
}

// Uso
const Api = ApiClient("https://api.exemplo.com");

const Usuario = struct {
    id: u64,
    nome: []const u8,
    email: []const u8,
};

pub fn main() !void {
    const allocator = std.heap.page_allocator;
    var api = Api.init(allocator);

    const usuario = try api.get(Usuario, "/usuarios/1");
    std.debug.print("Usuário: {s}\n", .{usuario.nome});
}
```

## Download de Arquivos

```zig
pub fn downloadArquivo(
    allocator: std.mem.Allocator,
    url: []const u8,
    caminho_saida: []const u8,
) !void {
    var client = std.http.Client{ .allocator = allocator };
    defer client.deinit();

    const uri = try std.Uri.parse(url);
    var buf: [8192]u8 = undefined;
    var req = try client.open(.GET, uri, .{
        .server_header_buffer = &buf,
    });
    defer req.deinit();

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

    // Salvar em arquivo
    const arquivo = try std.fs.cwd().createFile(caminho_saida, .{});
    defer arquivo.close();

    var read_buf: [8192]u8 = undefined;
    var reader = req.reader();
    while (true) {
        const n = try reader.read(&read_buf);
        if (n == 0) break;
        try arquivo.writeAll(read_buf[0..n]);
    }

    std.debug.print("Download concluído: {s}\n", .{caminho_saida});
}
```

## Retry com Backoff Exponencial

```zig
pub fn fetchComRetry(
    allocator: std.mem.Allocator,
    url: []const u8,
    max_tentativas: u32,
) ![]u8 {
    var tentativa: u32 = 0;
    while (tentativa < max_tentativas) : (tentativa += 1) {
        var client = std.http.Client{ .allocator = allocator };
        defer client.deinit();

        const uri = try std.Uri.parse(url);
        var buf: [8192]u8 = undefined;
        var req = client.open(.GET, uri, .{
            .server_header_buffer = &buf,
        }) catch |err| {
            std.debug.print("Tentativa {}: erro={}\n", .{ tentativa + 1, err });
            const delay = std.math.pow(u64, 2, tentativa) * std.time.ns_per_s;
            std.time.sleep(delay);
            continue;
        };
        defer req.deinit();

        req.send() catch continue;
        req.wait() catch continue;

        if (req.status == .ok) {
            return try req.reader().readAllAlloc(allocator, 1024 * 1024);
        }

        const delay = std.math.pow(u64, 2, tentativa) * std.time.ns_per_s;
        std.time.sleep(delay);
    }

    return error.MaxRetriesExceeded;
}
```

## Como este guia se conecta ao lado servidor

O cliente HTTP raramente vive sozinho. Em aplicações backend, ele costuma chamar APIs externas enquanto o mesmo serviço expõe endpoints próprios. Se esse é o seu caso, leia também o tutorial de [Zig Server HTTP com `std.http.Server`](/tutoriais/zig-http-server/), a receita de [HTTP POST em Zig](/receitas/zig-http-post-request/) e o checklist de [HTTP server em produção](/artigos/zig-http-server-producao/).

Essa trilha cobre o fluxo completo de uma API REST em Zig: receber uma requisição, validar JSON, chamar um serviço externo com `std.http.Client`, tratar status, registrar logs e responder com erro claro quando algo falha. Ela também ajuda a decidir quando a biblioteca padrão basta e quando faz sentido avaliar `httpz`, `zap` ou outra biblioteca do ecossistema.

## Boas Práticas

1. **Use `defer client.deinit()`**: Sempre libere recursos do cliente
2. **Trate status HTTP**: Verifique códigos de resposta antes de processar body
3. **Implemente timeouts**: Configure limites de tempo para evitar bloqueios
4. **Use keep-alive**: Reutilize conexões para múltiplas requisições ao mesmo host
5. **Valide certificados TLS**: O std.http.Client valida certificados por padrão

## Próximos Passos

Explore os [frameworks web](/ecossistema/httpz-web/) para o lado servidor, as [bibliotecas JSON](/ecossistema/zig-json-libs/) para parsing de respostas, e as [bibliotecas de rede](/ecossistema/zig-network/) para protocolos customizados. Para uma aplicação completa, combine este guia com [Zig Server HTTP: API REST com std.http.Server](/tutoriais/zig-http-server/) e [Zig HTTP Server em Produção](/artigos/zig-http-server-producao/). Veja como [Cloudflare](/cases/case-cloudflare-zig/) usa Zig em serviços HTTP e consulte nossos [tutoriais](/tutoriais/).
