Skip to content
/ zouter Public

[MIRROR] Zig HTTP router library.

License

Notifications You must be signed in to change notification settings

zigzedd/zouter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Zouter logo

Zouter

Zig HTTP router library

Zouter is part of zedd, a collection of useful libraries for zig.

Zouter for zap

Zouter is an HTTP router library for Zig zap HTTP server. It's made to ease the use of zap to build REST APIs.

Versions

Zouter 0.1.1 is made for zig 0.13.0 and tested with zap 0.8.0.

How to use

Install

In your project directory:

$ zig fetch --save https://code.zeptotech.net/zedd/zouter/archive/v0.1.1.tar.gz

In build.zig:

// Add zouter dependency.
const zouter = b.dependency("zouter", .{
	.target = target,
	.optimize = optimize,
});
exe.root_module.addImport("zouter", zouter.module("zouter"));

Example

Here is a quick example of how to set up a router. It is an extract from the full test code at example.zig. You may want to have a look to simple_routes.zig which shows more advanced features.

/// GET /foo/:arg/bar request handler.
fn get(route: zouter.MatchedRoute, request: zap.Request) !void {
	var bodyBuffer: [512]u8 = undefined;
	const body = try std.fmt.bufPrint(&bodyBuffer, "get: {s}", .{route.params.get("arg").?});
	try request.sendBody(body);
}

/// POST /foo/:arg/bar request handler.
fn post(route: zouter.MatchedRoute, request: zap.Request) !void {
	var bodyBuffer: [512]u8 = undefined;
	const body = try std.fmt.bufPrint(&bodyBuffer, "post: {s}", .{route.params.get("arg").?});
	try request.sendBody(body);
}

/// Setup an example router.
fn setupExampleRouter(allocator: std.mem.Allocator) !zouter.Router {
	// Initialize an example router.
	var exampleRouter = try zouter.Router.init(allocator, .{});

	// Add a route to the example router.
	try exampleRouter.route(.{
		.path = "foo",
		.children = &[_]zouter.RouteDefinition{
			.{
				.path = ":arg",
				.children = &[_]zouter.RouteDefinition{
					.{
						.path = "bar",
						.handle = .{
							.get = &get,
							.post = &post,
						},
					}
				},
			}
		},
	});

	return exampleRouter;
}

Route definition

A route only has one mandatory field: its path. If any part of a path starts with a ':', the value is taken as a dynamic variable, retrievable later with Route.params HashMap.

A route can have:

  • Children: sub-routes definitions, with a '/' between the parent and the child. It's useful to prefix a list of routes with the same path / variable.
  • Handle object: you can define a handle function for each HTTP basic request method. If you don't care about the request method, there is an any field which will be used for all undefined request methods.
  • Handle not found / error: you can define a custom functions to handle errors or not found pages inside this path.
  • Pre-handle / post-handle: these functions are started before and after the request handling in this path. It looks like middlewares and can assume the same role as most of them (e.g. a pre-handle function to check for authentication under a specific path).

Full details about route definition fields can be found in the API reference.