http.zig

· Robert Guiscard's Blog


http.zig is an easy-to-use http server for Zig. There are many alternatives. But this can be a good one to start prototyping.

First, create a zig project

$ cd new_project
$ zig init

Then add http.zig

$ zig fetch --save git+https://github.com/karlseguin/http.zig

You can see http.zig in the build.zig.zon.

To expose a module to the project, it needs to be a dependency in build.zig like this:

    // in build.zig

    const httpz_mod = b.dependency("httpz", .{
        .target = target,
        .optimize = optimize,
    }).module("httpz");

    exe_mod.addImport("httpz", httpz_mod);

This add httpz module into the executable exe_mode. Then use part of examples/01_basic.zig from http.zig project in src/main.zig

const std = @import("std");
const httpz = @import("httpz");
const Allocator = std.mem.Allocator;

const PORT = 8080;

// This example demonstrates basic httpz usage, with focus on using the
// httpz.Request and httpz.Response objects.

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

    // We pass a "void" handler. This is the simplest, but limits what we can do
    // The last parameter is an instance of our handler. Since we have
    // a void handler, we pass a void value: i.e. {}.
    var server = try httpz.Server(void).init(allocator, .{
        .port = PORT,
        .request = .{
            // httpz has a number of tweakable configuration settings (see readme)
            // by default, it won't read form data. We need to configure a max
            // field count (since one of our examples reads form data)
            .max_form_count = 20,
        },
    }, {});
    defer server.deinit();

    // ensures a clean shutdown, finishing off any existing requests
    // see 09_shutdown.zig for how to to break server.listen with an interrupt
    defer server.stop();

    var router = try server.router(.{});

    // Register routes. The last parameter is a Route Config. For these basic
    // examples, we aren't using it.
    // Other support methods: post, put, delete, head, trace, options and all
    router.get("/", index, .{});

    std.debug.print("listening http://localhost:{d}/\n", .{PORT});

    // Starts the server, this is blocking.
    try server.listen();
}

fn index(_: *httpz.Request, res: *httpz.Response) !void {
    res.body =
        \\<!DOCTYPE html>
        \\<p>Hello World!</p>
    ;
}

Bring up the web server via zig build run and connect to localhost:8080 from the web browser. It should show Hello World!.