bkataru

how to http_request.zig

note: these are rough scribblings and/or unfinished drafts, DO NOT use them in prod even if your life depends on it :')

everything was done in the latest version of zig (0.14.1 at the time of this writing)

const std = @import("std");

pub fn main() !void {
    const alloc = std.heap.page_allocator;
    var arena = std.heap.ArenaAllocator.init(alloc);
    const allocator = arena.allocator();
    defer arena.deinit();

    var client = std.http.Client{ .allocator = allocator };

    const headers = &[_]std.http.Header{
        .{ .name = "Content-Type", .value = "application/json" },
    };

    const response = try get(allocator, "https://jsonplaceholder.typicode.com/posts/1", headers, &client);

    const Result = struct {
        userId: i32,
        id: i32,
        title: []u8,
        body: []u8,
    };
    const result = try std.json.parseFromSlice(Result, allocator, response.items, .{ .ignore_unknown_fields = true });

    try std.io.getStdOut().writer().print("title: {s}\n", .{result.value.title});
}

fn get(
    allocator: std.mem.Allocator,
    url: []const u8,
    headers: []const std.http.Header,
    client: *std.http.Client,
) !std.ArrayList(u8) {
    const writer = std.io.getStdOut().writer();
    try writer.print("\nURL: {s} GET\n", .{url});
    var response_body = std.ArrayList(u8).init(allocator);
    errdefer response_body.deinit();

    try writer.print("Sending request...\n", .{});
    const response = try client.fetch(.{
        .method = .GET,
        .location = .{ .url = url },
        .extra_headers = headers,
        .response_storage = .{ .dynamic = &response_body },
    });
    try writer.print("Response Status: {d}\nResponse Body: {s}\n", .{ response.status, response_body.items });
    return response_body;
}

or if you'd prefer more low level control,

const std = @import("std");

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

    var buf: [4096]u8 = undefined;
    const uri = try std.Uri.parse("https://www.google.com?q=zig");
    var req = try client.open(.GET, uri, .{ .server_header_buffer = &buf });
    defer req.deinit();

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

    std.debug.print("status={d}\n", .{req.response.status});
}