mirror of
https://github.com/zigzap/zap.git
synced 2025-10-20 23:24:09 +00:00
endpoints, auth endpoints, middleware endpoints: eliminate need for empty stubs
This commit is contained in:
parent
baaa71d0e0
commit
dabd0637f9
9 changed files with 59 additions and 80 deletions
|
@ -59,7 +59,7 @@ const SimpleEndpoint = struct {
|
|||
try r.sendBody(response_text);
|
||||
std.time.sleep(std.time.ns_per_ms * 300);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const StopEndpoint = struct {
|
||||
path: []const u8,
|
||||
|
|
|
@ -13,11 +13,3 @@ pub fn get(_: *ErrorEndpoint, _: zap.Request) !void {
|
|||
// --> this error will be shown in the browser, with a nice error trace
|
||||
return error.@"Oh-no!";
|
||||
}
|
||||
|
||||
// unused:
|
||||
pub fn post(_: *ErrorEndpoint, _: zap.Request) !void {}
|
||||
pub fn put(_: *ErrorEndpoint, _: zap.Request) !void {}
|
||||
pub fn delete(_: *ErrorEndpoint, _: zap.Request) !void {}
|
||||
pub fn patch(_: *ErrorEndpoint, _: zap.Request) !void {}
|
||||
pub fn options(_: *ErrorEndpoint, _: zap.Request) !void {}
|
||||
pub fn head(_: *ErrorEndpoint, _: zap.Request) !void {}
|
||||
|
|
|
@ -17,10 +17,3 @@ pub fn init(path: []const u8) StopEndpoint {
|
|||
pub fn get(_: *StopEndpoint, _: zap.Request) !void {
|
||||
zap.stop();
|
||||
}
|
||||
|
||||
pub fn post(_: *StopEndpoint, _: zap.Request) !void {}
|
||||
pub fn put(_: *StopEndpoint, _: zap.Request) !void {}
|
||||
pub fn delete(_: *StopEndpoint, _: zap.Request) !void {}
|
||||
pub fn patch(_: *StopEndpoint, _: zap.Request) !void {}
|
||||
pub fn options(_: *StopEndpoint, _: zap.Request) !void {}
|
||||
pub fn head(_: *StopEndpoint, _: zap.Request) !void {}
|
||||
|
|
|
@ -43,7 +43,8 @@ fn userIdFromPath(self: *UserWeb, path: []const u8) ?usize {
|
|||
return null;
|
||||
}
|
||||
|
||||
pub fn put(_: *UserWeb, _: zap.Request) !void {}
|
||||
// not implemented
|
||||
// pub fn put(_: *UserWeb, _: zap.Request) !void {}
|
||||
|
||||
pub fn get(self: *UserWeb, r: zap.Request) !void {
|
||||
if (r.path) |path| {
|
||||
|
|
|
@ -31,14 +31,6 @@ const Endpoint = struct {
|
|||
r.setStatus(.unauthorized);
|
||||
r.sendBody("UNAUTHORIZED ACCESS") catch return;
|
||||
}
|
||||
|
||||
// not implemented, don't care
|
||||
pub fn post(_: *Endpoint, _: zap.Request) !void {}
|
||||
pub fn put(_: *Endpoint, _: zap.Request) !void {}
|
||||
pub fn delete(_: *Endpoint, _: zap.Request) !void {}
|
||||
pub fn patch(_: *Endpoint, _: zap.Request) !void {}
|
||||
pub fn options(_: *Endpoint, _: zap.Request) !void {}
|
||||
pub fn head(_: *Endpoint, _: zap.Request) !void {}
|
||||
};
|
||||
|
||||
pub fn main() !void {
|
||||
|
|
|
@ -152,13 +152,6 @@ const HtmlEndpoint = struct {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn post(_: *HtmlEndpoint, _: zap.Request) !void {}
|
||||
pub fn put(_: *HtmlEndpoint, _: zap.Request) !void {}
|
||||
pub fn delete(_: *HtmlEndpoint, _: zap.Request) !void {}
|
||||
pub fn patch(_: *HtmlEndpoint, _: zap.Request) !void {}
|
||||
pub fn options(_: *HtmlEndpoint, _: zap.Request) !void {}
|
||||
pub fn head(_: *HtmlEndpoint, _: zap.Request) !void {}
|
||||
|
||||
pub fn get(_: *HtmlEndpoint, r: zap.Request) !void {
|
||||
var buf: [1024]u8 = undefined;
|
||||
var userFound: bool = false;
|
||||
|
|
|
@ -5,7 +5,11 @@
|
|||
//! Pass an instance of an Endpoint struct to zap.Endpoint.Listener.register()
|
||||
//! function to register with the listener.
|
||||
//!
|
||||
//! **NOTE**: Endpoints must implement the following "interface":
|
||||
//! **NOTE**: Endpoints can implement the following "interface":
|
||||
//!
|
||||
//! Any method handler that's not implemented will be handled automatically:
|
||||
//! - zap will log it
|
||||
//! - a response with status code 405 (method not allowed) is sent to the client
|
||||
//!
|
||||
//! ```zig
|
||||
//! /// The http request path / slug of the endpoint
|
||||
|
@ -13,6 +17,7 @@
|
|||
//! error_strategy: zap.Endpoint.ErrorStrategy,
|
||||
//!
|
||||
//! /// Handlers by request method:
|
||||
//! /// implement any of the following
|
||||
//! pub fn get(_: *Self, _: zap.Request) !void {}
|
||||
//! pub fn post(_: *Self, _: zap.Request) !void {}
|
||||
//! pub fn put(_: *Self, _: zap.Request) !void {}
|
||||
|
@ -44,13 +49,6 @@
|
|||
//! pub fn get(_: *StopEndpoint, _: zap.Request) !void {
|
||||
//! zap.stop();
|
||||
//! }
|
||||
//!
|
||||
//! pub fn post(_: *StopEndpoint, _: zap.Request) !void {}
|
||||
//! pub fn put(_: *StopEndpoint, _: zap.Request) !void {}
|
||||
//! pub fn delete(_: *StopEndpoint, _: zap.Request) !void {}
|
||||
//! pub fn patch(_: *StopEndpoint, _: zap.Request) !void {}
|
||||
//! pub fn options(_: *StopEndpoint, _: zap.Request) !void {}
|
||||
//! pub fn head(_: *StopEndpoint, _: zap.Request) !void {}
|
||||
//! };
|
||||
//! ```
|
||||
|
||||
|
@ -154,10 +152,25 @@ pub fn checkEndpointType(T: type) void {
|
|||
@compileError("Expected return type of method `" ++ @typeName(T) ++ "." ++ method ++ "` to be !void, got: !" ++ @typeName(ret_info.error_union.payload));
|
||||
}
|
||||
} else {
|
||||
@compileError(@typeName(T) ++ " has no method named `" ++ method ++ "`");
|
||||
// it is ok not to implement a method handler
|
||||
// pass
|
||||
}
|
||||
}
|
||||
}
|
||||
// This can be resolved at comptime so *perhaps it does affect optimiazation
|
||||
pub fn callHandlerIfExist(comptime fn_name: []const u8, e: anytype, r: Request) anyerror!void {
|
||||
const EndPointType = @TypeOf(e.*);
|
||||
if (@hasDecl(EndPointType, fn_name)) {
|
||||
return @field(EndPointType, fn_name)(e, r);
|
||||
}
|
||||
zap.log.debug(
|
||||
"Unhandled `{s}` {s} request ({s} not implemented in {s})",
|
||||
.{ r.method orelse "<unknown>", r.path orelse "", fn_name, @typeName(EndPointType) },
|
||||
);
|
||||
r.setStatus(.method_not_allowed);
|
||||
try r.sendBody("405 - method not allowed\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pub const Binder = struct {
|
||||
pub const Interface = struct {
|
||||
|
@ -189,13 +202,13 @@ pub const Binder = struct {
|
|||
|
||||
pub fn onRequest(self: *Bound, r: zap.Request) !void {
|
||||
const ret = switch (r.methodAsEnum()) {
|
||||
.GET => self.endpoint.*.get(r),
|
||||
.POST => self.endpoint.*.post(r),
|
||||
.PUT => self.endpoint.*.put(r),
|
||||
.DELETE => self.endpoint.*.delete(r),
|
||||
.PATCH => self.endpoint.*.patch(r),
|
||||
.OPTIONS => self.endpoint.*.options(r),
|
||||
.HEAD => self.endpoint.*.head(r),
|
||||
.GET => callHandlerIfExist("get", self.endpoint, r),
|
||||
.POST => callHandlerIfExist("post", self.endpoint, r),
|
||||
.PUT => callHandlerIfExist("put", self.endpoint, r),
|
||||
.DELETE => callHandlerIfExist("delete", self.endpoint, r),
|
||||
.PATCH => callHandlerIfExist("patch", self.endpoint, r),
|
||||
.OPTIONS => callHandlerIfExist("options", self.endpoint, r),
|
||||
.HEAD => callHandlerIfExist("head", self.endpoint, r),
|
||||
else => error.UnsupportedHtmlRequestMethod,
|
||||
};
|
||||
if (ret) {
|
||||
|
@ -249,8 +262,8 @@ pub fn Authenticating(EndpointType: type, Authenticator: type) type {
|
|||
/// Authenticates GET requests using the Authenticator.
|
||||
pub fn get(self: *AuthenticatingEndpoint, r: zap.Request) anyerror!void {
|
||||
try switch (self.authenticator.authenticateRequest(&r)) {
|
||||
.AuthFailed => return self.ep.*.unauthorized(r),
|
||||
.AuthOK => self.ep.*.get(r),
|
||||
.AuthFailed => callHandlerIfExist("unauthorized", self.ep, r),
|
||||
.AuthOK => callHandlerIfExist("get", self.ep, r),
|
||||
.Handled => {},
|
||||
};
|
||||
}
|
||||
|
@ -258,8 +271,8 @@ pub fn Authenticating(EndpointType: type, Authenticator: type) type {
|
|||
/// Authenticates POST requests using the Authenticator.
|
||||
pub fn post(self: *AuthenticatingEndpoint, r: zap.Request) anyerror!void {
|
||||
try switch (self.authenticator.authenticateRequest(&r)) {
|
||||
.AuthFailed => return self.ep.*.unauthorized(r),
|
||||
.AuthOK => self.ep.*.post(r),
|
||||
.AuthFailed => callHandlerIfExist("unauthorized", self.ep, r),
|
||||
.AuthOK => callHandlerIfExist("post", self.ep, r),
|
||||
.Handled => {},
|
||||
};
|
||||
}
|
||||
|
@ -267,8 +280,8 @@ pub fn Authenticating(EndpointType: type, Authenticator: type) type {
|
|||
/// Authenticates PUT requests using the Authenticator.
|
||||
pub fn put(self: *AuthenticatingEndpoint, r: zap.Request) anyerror!void {
|
||||
try switch (self.authenticator.authenticateRequest(&r)) {
|
||||
.AuthFailed => return self.ep.*.unauthorized(r),
|
||||
.AuthOK => self.ep.*.put(r),
|
||||
.AuthFailed => callHandlerIfExist("unauthorized", self.ep, r),
|
||||
.AuthOK => callHandlerIfExist("put", self.ep, r),
|
||||
.Handled => {},
|
||||
};
|
||||
}
|
||||
|
@ -276,8 +289,8 @@ pub fn Authenticating(EndpointType: type, Authenticator: type) type {
|
|||
/// Authenticates DELETE requests using the Authenticator.
|
||||
pub fn delete(self: *AuthenticatingEndpoint, r: zap.Request) anyerror!void {
|
||||
try switch (self.authenticator.authenticateRequest(&r)) {
|
||||
.AuthFailed => return self.ep.*.unauthorized(r),
|
||||
.AuthOK => self.ep.*.delete(r),
|
||||
.AuthFailed => callHandlerIfExist("unauthorized", self.ep, r),
|
||||
.AuthOK => callHandlerIfExist("delete", self.ep, r),
|
||||
.Handled => {},
|
||||
};
|
||||
}
|
||||
|
@ -285,8 +298,8 @@ pub fn Authenticating(EndpointType: type, Authenticator: type) type {
|
|||
/// Authenticates PATCH requests using the Authenticator.
|
||||
pub fn patch(self: *AuthenticatingEndpoint, r: zap.Request) anyerror!void {
|
||||
try switch (self.authenticator.authenticateRequest(&r)) {
|
||||
.AuthFailed => return self.ep.*.unauthorized(r),
|
||||
.AuthOK => self.ep.*.patch(r),
|
||||
.AuthFailed => callHandlerIfExist("unauthorized", self.ep, r),
|
||||
.AuthOK => callHandlerIfExist("patch", self.ep, r),
|
||||
.Handled => {},
|
||||
};
|
||||
}
|
||||
|
@ -294,8 +307,8 @@ pub fn Authenticating(EndpointType: type, Authenticator: type) type {
|
|||
/// Authenticates OPTIONS requests using the Authenticator.
|
||||
pub fn options(self: *AuthenticatingEndpoint, r: zap.Request) anyerror!void {
|
||||
try switch (self.authenticator.authenticateRequest(&r)) {
|
||||
.AuthFailed => return self.ep.*.unauthorized(r),
|
||||
.AuthOK => self.ep.*.put(r),
|
||||
.AuthFailed => callHandlerIfExist("unauthorized", self.ep, r),
|
||||
.AuthOK => callHandlerIfExist("options", self.ep, r),
|
||||
.Handled => {},
|
||||
};
|
||||
}
|
||||
|
@ -303,8 +316,8 @@ pub fn Authenticating(EndpointType: type, Authenticator: type) type {
|
|||
/// Authenticates HEAD requests using the Authenticator.
|
||||
pub fn head(self: *AuthenticatingEndpoint, r: zap.Request) anyerror!void {
|
||||
try switch (self.authenticator.authenticateRequest(&r)) {
|
||||
.AuthFailed => return self.ep.*.unauthorized(r),
|
||||
.AuthOK => self.ep.*.head(r),
|
||||
.AuthFailed => callHandlerIfExist("unauthorized", self.ep, r),
|
||||
.AuthOK => callHandlerIfExist("head", self.ep, r),
|
||||
.Handled => {},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const std = @import("std");
|
||||
const zap = @import("zap.zig");
|
||||
const callHandlerIfExist = @import("endpoint.zig").callHandlerIfExist;
|
||||
|
||||
/// Your middleware components need to contain a handler.
|
||||
///
|
||||
|
@ -102,16 +103,16 @@ pub fn EndpointHandler(comptime HandlerType: anytype, comptime EndpointType: any
|
|||
if (!self.options.checkPath or
|
||||
std.mem.startsWith(u8, r.path orelse "", self.endpoint.path))
|
||||
{
|
||||
switch (r.methodAsEnum()) {
|
||||
.GET => try self.endpoint.*.get(r),
|
||||
.POST => try self.endpoint.*.post(r),
|
||||
.PUT => try self.endpoint.*.put(r),
|
||||
.DELETE => try self.endpoint.*.delete(r),
|
||||
.PATCH => try self.endpoint.*.patch(r),
|
||||
.OPTIONS => try self.endpoint.*.options(r),
|
||||
.HEAD => try self.endpoint.*.head(r),
|
||||
try switch (r.methodAsEnum()) {
|
||||
.GET => callHandlerIfExist("get", self.endpoint, r),
|
||||
.POST => callHandlerIfExist("post", self.endpoint, r),
|
||||
.PUT => callHandlerIfExist("put", self.endpoint, r),
|
||||
.DELETE => callHandlerIfExist("delete", self.endpoint, r),
|
||||
.PATCH => callHandlerIfExist("patch", self.endpoint, r),
|
||||
.OPTIONS => callHandlerIfExist("options", self.endpoint, r),
|
||||
.HEAD => callHandlerIfExist("head", self.endpoint, r),
|
||||
else => {},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// if the request was handled by the endpoint, we may break the chain here
|
||||
|
|
|
@ -165,12 +165,6 @@ pub const Endpoint = struct {
|
|||
std.time.sleep(1 * std.time.ns_per_s);
|
||||
zap.stop();
|
||||
}
|
||||
pub fn post(_: *Endpoint, _: zap.Request) !void {}
|
||||
pub fn put(_: *Endpoint, _: zap.Request) !void {}
|
||||
pub fn delete(_: *Endpoint, _: zap.Request) !void {}
|
||||
pub fn patch(_: *Endpoint, _: zap.Request) !void {}
|
||||
pub fn options(_: *Endpoint, _: zap.Request) !void {}
|
||||
pub fn head(_: *Endpoint, _: zap.Request) !void {}
|
||||
};
|
||||
//
|
||||
// end of http client code
|
||||
|
|
Loading…
Add table
Reference in a new issue