Skip to content

Commit

Permalink
API cleanup #1 --------------
Browse files Browse the repository at this point in the history
- EndpointListener.register() // was: addEndpoint
- no more Simple
- getEndpoint -> endpoint()
  • Loading branch information
renerocksai committed Jan 9, 2024
1 parent 804c037 commit 8892cae
Show file tree
Hide file tree
Showing 31 changed files with 352 additions and 251 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ what's necessary to show a feature.
less type-safe than `zap.Middleware`'s use of contexts.
- [**Per Request Contexts**](./src/zap.zig#L102) : With the introduction of
`setUserContext()` and `getUserContext()`, you can, of course use those two in
projects that don't use `zap.SimpleEndpoint` or `zap.Middleware`, too, if you
projects that don't use `zap.Endpoint` or `zap.Middleware`, too, if you
really, really, absolutely don't find another way to solve your context
problem. **We recommend using a `zap.SimpleEndpoint`** inside of a struct that
problem. **We recommend using a `zap.Endpoint`** inside of a struct that
can provide all the context you need **instead**. You get access to your
struct in the callbacks via the `@fieldParentPtr()` trick that is used
extensively in Zap's examples, like the [endpoint
Expand Down Expand Up @@ -369,7 +369,7 @@ $ zig build run-routes
const std = @import("std");
const zap = @import("zap");
fn on_request(r: zap.SimpleRequest) void {
fn on_request(r: zap.Request) void {
if (r.path) |the_path| {
std.debug.print("PATH: {s}\n", .{the_path});
}
Expand All @@ -381,7 +381,7 @@ fn on_request(r: zap.SimpleRequest) void {
}
pub fn main() !void {
var listener = zap.SimpleHttpListener.init(.{
var listener = zap.HttpListener.init(.{
.port = 3000,
.on_request = on_request,
.log = true,
Expand Down
20 changes: 10 additions & 10 deletions doc/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ For convenience, Authenticator types exist that can authenticate requests.
Zap also provides an `AuthenticatingEndpoint` endpoint-wrapper. Have a look at the [example](../examples/endpoint_auth) and the [tests](../src/tests/test_auth.zig).

The following describes the Authenticator types. All of them provide the
`authenticateRequest()` function, which takes a `zap.SimpleRequest` and returns
`authenticateRequest()` function, which takes a `zap.Request` and returns
a bool value whether it could be authenticated or not.

Further down, we show how to use the Authenticators, and also the
Expand Down Expand Up @@ -60,7 +60,7 @@ var auth = try zap.BearerAuthSingle.init(allocator, token, null);
defer auth.deinit();
fn on_request(r: zap.SimpleRequest) void {
fn on_request(r: zap.Request) void {
if(authenticator.authenticateRequest(r)) {
r.sendBody(
\\ <html><body>
Expand Down Expand Up @@ -94,7 +94,7 @@ var auth = try zap.BearerAuthMulti(Set).init(allocator, &set, null);
defer auth.deinit();
fn on_request(r: zap.SimpleRequest) void {
fn on_request(r: zap.Request) void {
if(authenticator.authenticateRequest(r)) {
r.sendBody(
\\ <html><body>
Expand Down Expand Up @@ -132,7 +132,7 @@ var auth = try Authenticator.init(a, &map, null);
defer auth.deinit();
fn on_request(r: zap.SimpleRequest) void {
fn on_request(r: zap.Request) void {
if(authenticator.authenticateRequest(r)) {
r.sendBody(
\\ <html><body>
Expand Down Expand Up @@ -168,7 +168,7 @@ var auth = try Authenticator.init(allocator, &set, null);
defer auth.deinit();
fn on_request(r: zap.SimpleRequest) void {
fn on_request(r: zap.Request) void {
if(authenticator.authenticateRequest(r)) {
r.sendBody(
\\ <html><body>
Expand Down Expand Up @@ -206,21 +206,21 @@ const HTTP_RESPONSE: []const u8 =
;
// authenticated requests go here
fn endpoint_http_get(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
fn endpoint_http_get(e: *zap.Endpoint, r: zap.Request) void {
_ = e;
r.sendBody(HTTP_RESPONSE) catch return;
}
// just for fun, we also catch the unauthorized callback
fn endpoint_http_unauthorized(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
fn endpoint_http_unauthorized(e: *zap.Endpoint, r: zap.Request) void {
_ = e;
r.setStatus(.unauthorized);
r.sendBody("UNAUTHORIZED ACCESS") catch return;
}
pub fn main() !void {
// setup listener
var listener = zap.SimpleEndpointListener.init(
var listener = zap.EndpointListener.init(
a,
.{
.port = 3000,
Expand All @@ -233,7 +233,7 @@ pub fn main() !void {
defer listener.deinit();
// create mini endpoint
var ep = zap.SimpleEndpoint.init(.{
var ep = zap.Endpoint.init(.{
.path = "/test",
.get = endpoint_http_get,
.unauthorized = endpoint_http_unauthorized,
Expand All @@ -248,7 +248,7 @@ pub fn main() !void {
const BearerAuthEndpoint = zap.AuthenticatingEndpoint(Authenticator);
var auth_ep = BearerAuthEndpoint.init(&ep, &authenticator);
try listener.addEndpoint(auth_ep.getEndpoint());
try listener.register(auth_ep.endpoint());
listener.listen() catch {};
std.debug.print(
Expand Down
4 changes: 2 additions & 2 deletions doc/why-no-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ Now that I think I've made my point 😊, you can, of course always do the
following:

```zig
fn on_request_with_errors(r: zap.SimpleHttpRequest) !void {
fn on_request_with_errors(r: zap.HttpRequest) !void {
// do all the try stuff here
}
```

```zig
// THIS IS WHAT YOU PASS TO THE LISTENER / ENDPONT / ...
fn on_request(r: zap.SimpleHttpRequest) void {
fn on_request(r: zap.HttpRequest) void {
on_request_with_errors(r) catch |err| {
// log the error or use:
return r.returnWithErrorStackTrace(err);
Expand Down
4 changes: 2 additions & 2 deletions examples/bindataformpost/bindataformpost.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const zap = @import("zap");
const Handler = struct {
var alloc: std.mem.Allocator = undefined;

pub fn on_request(r: zap.SimpleRequest) void {
pub fn on_request(r: zap.Request) void {
// check for FORM parameters
r.parseBody() catch |err| {
std.log.err("Parse Body error: {any}. Expected if body is empty", .{err});
Expand Down Expand Up @@ -92,7 +92,7 @@ pub fn main() !void {
Handler.alloc = allocator;

// setup listener
var listener = zap.SimpleHttpListener.init(
var listener = zap.HttpListener.init(
.{
.port = 3000,
.on_request = Handler.on_request,
Expand Down
4 changes: 2 additions & 2 deletions examples/cookies/cookies.zig
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub fn main() !void {
const Handler = struct {
var alloc: std.mem.Allocator = undefined;

pub fn on_request(r: zap.SimpleRequest) void {
pub fn on_request(r: zap.Request) void {
std.debug.print("\n=====================================================\n", .{});
defer std.debug.print("=====================================================\n\n", .{});

Expand Down Expand Up @@ -98,7 +98,7 @@ pub fn main() !void {
Handler.alloc = allocator;

// setup listener
var listener = zap.SimpleHttpListener.init(
var listener = zap.HttpListener.init(
.{
.port = 3000,
.on_request = Handler.on_request,
Expand Down
21 changes: 11 additions & 10 deletions examples/endpoint/main.zig
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const std = @import("std");
const zap = @import("zap");
const Endpoint = @import("endpoint.zig");
const UserWeb = @import("userweb.zig");
const StopEndpoint = @import("stopendpoint.zig");

// this is just to demo that we can catch arbitrary slugs
fn on_request(r: zap.SimpleRequest) void {
fn on_request(r: zap.Request) void {
if (r.path) |the_path| {
std.debug.print("REQUESTED PATH: {s}\n", .{the_path});
}
Expand All @@ -21,7 +21,7 @@ pub fn main() !void {
// we scope everything that can allocate within this block for leak detection
{
// setup listener
var listener = zap.SimpleEndpointListener.init(
var listener = zap.EndpointListener.init(
allocator,
.{
.port = 3000,
Expand All @@ -34,19 +34,20 @@ pub fn main() !void {
);
defer listener.deinit();

var endpoint = Endpoint.init(allocator, "/users");
defer endpoint.deinit();
// /users endpoint
var userWeb = UserWeb.init(allocator, "/users");
defer userWeb.deinit();

var stopEp = StopEndpoint.init("/stop");

// add endpoint
try listener.addEndpoint(endpoint.getUserEndpoint());
try listener.addEndpoint(stopEp.getEndpoint());
// register endpoints with the listener
try listener.register(userWeb.endpoint());
try listener.register(stopEp.endpoint());

// fake some users
var uid: usize = undefined;
uid = try endpoint.getUsers().addByName("renerocksai", null);
uid = try endpoint.getUsers().addByName("renerocksai", "your mom");
uid = try userWeb.users().addByName("renerocksai", null);
uid = try userWeb.users().addByName("renerocksai", "your mom");

// listen
try listener.listen();
Expand Down
10 changes: 5 additions & 5 deletions examples/endpoint/stopendpoint.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@ const zap = @import("zap");
/// the main thread usually continues at the instructions after the call to zap.start().
pub const Self = @This();

endpoint: zap.SimpleEndpoint = undefined,
ep: zap.Endpoint = undefined,

pub fn init(
path: []const u8,
) Self {
return .{
.endpoint = zap.SimpleEndpoint.init(.{
.ep = zap.Endpoint.init(.{
.path = path,
.get = get,
}),
};
}

pub fn getEndpoint(self: *Self) *zap.SimpleEndpoint {
return &self.endpoint;
pub fn endpoint(self: *Self) *zap.Endpoint {
return &self.ep;
}

fn get(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
fn get(e: *zap.Endpoint, r: zap.Request) void {
_ = e;
_ = r;
zap.stop();
Expand Down
56 changes: 28 additions & 28 deletions examples/endpoint/endpoint.zig → examples/endpoint/userweb.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ const User = Users.User;
pub const Self = @This();

alloc: std.mem.Allocator = undefined,
endpoint: zap.SimpleEndpoint = undefined,
users: Users = undefined,
ep: zap.Endpoint = undefined,
_users: Users = undefined,

pub fn init(
a: std.mem.Allocator,
user_path: []const u8,
) Self {
return .{
.alloc = a,
.users = Users.init(a),
.endpoint = zap.SimpleEndpoint.init(.{
._users = Users.init(a),
.ep = zap.Endpoint.init(.{
.path = user_path,
.get = getUser,
.post = postUser,
Expand All @@ -31,38 +31,38 @@ pub fn init(
}

pub fn deinit(self: *Self) void {
self.users.deinit();
self._users.deinit();
}

pub fn getUsers(self: *Self) *Users {
return &self.users;
pub fn users(self: *Self) *Users {
return &self._users;
}

pub fn getUserEndpoint(self: *Self) *zap.SimpleEndpoint {
return &self.endpoint;
pub fn endpoint(self: *Self) *zap.Endpoint {
return &self.ep;
}

fn userIdFromPath(self: *Self, path: []const u8) ?usize {
if (path.len >= self.endpoint.settings.path.len + 2) {
if (path[self.endpoint.settings.path.len] != '/') {
if (path.len >= self.ep.settings.path.len + 2) {
if (path[self.ep.settings.path.len] != '/') {
return null;
}
const idstr = path[self.endpoint.settings.path.len + 1 ..];
const idstr = path[self.ep.settings.path.len + 1 ..];
return std.fmt.parseUnsigned(usize, idstr, 10) catch null;
}
return null;
}

fn getUser(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
const self = @fieldParentPtr(Self, "endpoint", e);
fn getUser(e: *zap.Endpoint, r: zap.Request) void {
const self = @fieldParentPtr(Self, "ep", e);
if (r.path) |path| {
// /users
if (path.len == e.settings.path.len) {
return self.listUsers(r);
}
var jsonbuf: [256]u8 = undefined;
if (self.userIdFromPath(path)) |id| {
if (self.users.get(id)) |user| {
if (self._users.get(id)) |user| {
if (zap.stringifyBuf(&jsonbuf, user, .{})) |json| {
r.sendJson(json) catch return;
}
Expand All @@ -71,22 +71,22 @@ fn getUser(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
}
}

fn listUsers(self: *Self, r: zap.SimpleRequest) void {
if (self.users.toJSON()) |json| {
fn listUsers(self: *Self, r: zap.Request) void {
if (self._users.toJSON()) |json| {
defer self.alloc.free(json);
r.sendJson(json) catch return;
} else |err| {
std.debug.print("LIST error: {}\n", .{err});
}
}

fn postUser(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
const self = @fieldParentPtr(Self, "endpoint", e);
fn postUser(e: *zap.Endpoint, r: zap.Request) void {
const self = @fieldParentPtr(Self, "ep", e);
if (r.body) |body| {
var maybe_user: ?std.json.Parsed(User) = std.json.parseFromSlice(User, self.alloc, body, .{}) catch null;
if (maybe_user) |u| {
defer u.deinit();
if (self.users.addByName(u.value.first_name, u.value.last_name)) |id| {
if (self._users.addByName(u.value.first_name, u.value.last_name)) |id| {
var jsonbuf: [128]u8 = undefined;
if (zap.stringifyBuf(&jsonbuf, .{ .status = "OK", .id = id }, .{})) |json| {
r.sendJson(json) catch return;
Expand All @@ -99,17 +99,17 @@ fn postUser(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
}
}

fn putUser(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
const self = @fieldParentPtr(Self, "endpoint", e);
fn putUser(e: *zap.Endpoint, r: zap.Request) void {
const self = @fieldParentPtr(Self, "ep", e);
if (r.path) |path| {
if (self.userIdFromPath(path)) |id| {
if (self.users.get(id)) |_| {
if (self._users.get(id)) |_| {
if (r.body) |body| {
var maybe_user: ?std.json.Parsed(User) = std.json.parseFromSlice(User, self.alloc, body, .{}) catch null;
if (maybe_user) |u| {
defer u.deinit();
var jsonbuf: [128]u8 = undefined;
if (self.users.update(id, u.value.first_name, u.value.last_name)) {
if (self._users.update(id, u.value.first_name, u.value.last_name)) {
if (zap.stringifyBuf(&jsonbuf, .{ .status = "OK", .id = id }, .{})) |json| {
r.sendJson(json) catch return;
}
Expand All @@ -125,12 +125,12 @@ fn putUser(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
}
}

fn deleteUser(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
const self = @fieldParentPtr(Self, "endpoint", e);
fn deleteUser(e: *zap.Endpoint, r: zap.Request) void {
const self = @fieldParentPtr(Self, "ep", e);
if (r.path) |path| {
if (self.userIdFromPath(path)) |id| {
var jsonbuf: [128]u8 = undefined;
if (self.users.delete(id)) {
if (self._users.delete(id)) {
if (zap.stringifyBuf(&jsonbuf, .{ .status = "OK", .id = id }, .{})) |json| {
r.sendJson(json) catch return;
}
Expand All @@ -143,7 +143,7 @@ fn deleteUser(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
}
}

fn optionsUser(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
fn optionsUser(e: *zap.Endpoint, r: zap.Request) void {
_ = e;
r.setHeader("Access-Control-Allow-Origin", "*") catch return;
r.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS") catch return;
Expand Down
Loading

0 comments on commit 8892cae

Please sign in to comment.