An HTTP/1.1 server for zig
0

Configure Feed

Select the types of activity you want to include in your feed.

http.zig / examples / 07_advanced_routing.zig
3.4 kB 95 lines
1const std = @import("std"); 2const httpz = @import("httpz"); 3 4const Io = std.Io; 5const Allocator = std.mem.Allocator; 6 7const PORT = 8807; 8 9// This example shows more advanced routing example, namely route groups 10// and route configuration. (The previous example, with middleware, also showed 11// per-route configuration for middleware specifically). 12 13pub fn main(init: std.process.Init) !void { 14 const allocator = init.gpa; 15 16 var default_handler = Handler{ 17 .io = init.io, 18 .log = true, 19 }; 20 21 var nolog_handler = Handler{ 22 .io = init.io, 23 .log = false, 24 }; 25 26 var server = try httpz.Server(*Handler).init(init.io, allocator, .{ .address = .localhost(PORT) }, &default_handler); 27 28 defer server.deinit(); 29 30 // ensures a clean shutdown, finishing off any existing requests 31 // see 09_shutdown.zig for how to to break server.listen with an interrupt 32 defer server.stop(); 33 34 var router = try server.router(.{}); 35 36 router.get("/", index, .{}); 37 38 // We can define a dispatch function per-route. This will be used instead of Handler.dispatch 39 // But, sadly, every dispatch method must have the same signature (they must all accept the same type of action) 40 router.get("/page1", page1, .{ .dispatcher = Handler.infoDispatch }); 41 42 // We can define a handler instance per-route. This will be used instead of the 43 // handler instance passed to the init method above. 44 router.get("/page2", page2, .{ .handler = &nolog_handler }); 45 46 std.debug.print("listening http://localhost:{d}/\n", .{PORT}); 47 48 // Starts the server, this is blocking. 49 try server.listen(); 50} 51 52const Handler = struct { 53 io: Io, 54 log: bool, 55 56 // special dispatch set in the info route 57 pub fn infoDispatch(h: *Handler, action: httpz.Action(*Handler), req: *httpz.Request, res: *httpz.Response) !void { 58 return action(h, req, res); 59 } 60 61 pub fn dispatch(h: *Handler, action: httpz.Action(*Handler), req: *httpz.Request, res: *httpz.Response) !void { 62 try action(h, req, res); 63 if (h.log) { 64 std.debug.print("ts={d} path={s} status={d}\n", .{ Io.Timestamp.now(h.io, .real), req.url.path, res.status }); 65 } 66 } 67}; 68 69fn index(_: *Handler, _: *httpz.Request, res: *httpz.Response) !void { 70 res.content_type = .HTML; 71 res.body = 72 \\<!DOCTYPE html> 73 \\ <p>It's possible to define a custom dispatch method, custom handler instance and/or custom middleware per-route. 74 \\ <p>It's also possible to create a route group, which is a group of routes who share a common prefix and/or a custom configration. 75 \\ <ul> 76 \\ <li><a href="/page1">page with custom dispatch</a> 77 \\ <li><a href="/page2">page with custom handler</a> 78 ; 79} 80 81fn page1(_: *Handler, _: *httpz.Request, res: *httpz.Response) !void { 82 // Called with a custom config which specified a custom dispatch method 83 res.body = 84 \\ Accessing this endpoint will NOT generate a log line in the console, 85 \\ because a custom dispatch method is used 86 ; 87} 88 89fn page2(_: *Handler, _: *httpz.Request, res: *httpz.Response) !void { 90 // Called with a custom config which specified a custom handler instance 91 res.body = 92 \\ Accessing this endpoint will NOT generate a log line in the console, 93 \\ because a custom handler instance is used 94 ; 95}