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 / 01_basic.zig
4.3 kB 125 lines
1const std = @import("std"); 2const httpz = @import("httpz"); 3const Allocator = std.mem.Allocator; 4 5const PORT = 8801; 6 7// This example demonstrates basic httpz usage, with focus on using the 8// httpz.Request and httpz.Response objects. 9 10pub fn main(init: std.process.Init) !void { 11 const allocator = init.gpa; 12 13 // We pass a "void" handler. This is the simplest, but limits what we can do 14 // The last parameter is an instance of our handler. Since we have 15 // a void handler, we pass a void value: i.e. {}. 16 var server = try httpz.Server(void).init(init.io, allocator, .{ 17 .address = .localhost(PORT), 18 .request = .{ 19 // httpz has a number of tweakable configuration settings (see readme) 20 // by default, it won't read form data. We need to configure a max 21 // field count (since one of our examples reads form data) 22 .max_form_count = 20, 23 }, 24 }, {}); 25 defer server.deinit(); 26 27 // ensures a clean shutdown, finishing off any existing requests 28 // see 09_shutdown.zig for how to to break server.listen with an interrupt 29 defer server.stop(); 30 31 var router = try server.router(.{}); 32 33 // Register routes. The last parameter is a Route Config. For these basic 34 // examples, we aren't using it. 35 // Other support methods: post, put, delete, head, trace, options and all 36 router.get("/", index, .{}); 37 router.get("/hello", hello, .{}); 38 router.get("/json/hello/:name", json, .{}); 39 router.get("/writer/hello/:name", writer, .{}); 40 router.get("/metrics", metrics, .{}); 41 router.get("/form_data", formShow, .{}); 42 router.post("/form_data", formPost, .{}); 43 router.get("/explicit_write", explicitWrite, .{}); 44 45 std.debug.print("listening http://localhost:{d}/\n", .{PORT}); 46 47 // Starts the server, this is blocking. 48 try server.listen(); 49} 50 51fn index(_: *httpz.Request, res: *httpz.Response) !void { 52 res.body = 53 \\<!DOCTYPE html> 54 \\ <ul> 55 \\ <li><a href="/hello?name=Teg">Querystring + text output</a> 56 \\ <li><a href="/writer/hello/Ghanima">Path parameter + serialize json object</a> 57 \\ <li><a href="/json/hello/Duncan">Path parameter + json writer</a> 58 \\ <li><a href="/metrics">Internal metrics</a> 59 \\ <li><a href="/form_data">Form Data</a> 60 \\ <li><a href="/explicit_write">Explicit Write</a> 61 ; 62} 63 64fn hello(req: *httpz.Request, res: *httpz.Response) !void { 65 const query = try req.query(); 66 const name = query.get("name") orelse "stranger"; 67 68 // Could also see res.writer(), see the writer endpoint for an example 69 res.body = try std.fmt.allocPrint(res.arena, "Hello {s}", .{name}); 70} 71 72fn json(req: *httpz.Request, res: *httpz.Response) !void { 73 const name = req.param("name").?; 74 75 // the last parameter to res.json is an std.json.StringifyOptions 76 try res.json(.{ .hello = name }, .{}); 77} 78 79fn writer(req: *httpz.Request, res: *httpz.Response) !void { 80 res.content_type = httpz.ContentType.JSON; 81 82 const name = req.param("name").?; 83 84 try std.json.Stringify.value( 85 .{ .name = name }, 86 .{ .whitespace = .indent_4 }, 87 res.writer(), 88 ); 89} 90 91fn metrics(_: *httpz.Request, res: *httpz.Response) !void { 92 // httpz exposes some prometheus-style metrics 93 return httpz.writeMetrics(res.writer()); 94} 95 96fn formShow(_: *httpz.Request, res: *httpz.Response) !void { 97 res.body = 98 \\ <html> 99 \\ <form method=post> 100 \\ <p><input name=name value=goku></p> 101 \\ <p><input name=power value=9001></p> 102 \\ <p><input type=submit value=submit></p> 103 \\ </form> 104 ; 105} 106 107fn formPost(req: *httpz.Request, res: *httpz.Response) !void { 108 var it = (try req.formData()).iterator(); 109 110 res.content_type = .TEXT; 111 112 const w = res.writer(); 113 while (it.next()) |kv| { 114 try w.print("{s}={s}\n", .{ kv.key, kv.value }); 115 } 116} 117 118fn explicitWrite(_: *httpz.Request, res: *httpz.Response) !void { 119 res.body = 120 \\ There may be cases where your response is tied to data which 121 \\ required cleanup. If `res.arena` and `res.writer()` can't solve 122 \\ the issue, you can always call `res.write()` explicitly 123 ; 124 return res.write(); 125}