aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/api/hello-body.zig20
-rw-r--r--src/api/hello-json.zig15
-rw-r--r--src/api/hello-param.zig14
-rw-r--r--src/api/root.zig17
-rw-r--r--src/http/Response.zig17
5 files changed, 82 insertions, 1 deletions
diff --git a/src/api/hello-body.zig b/src/api/hello-body.zig
new file mode 100644
index 0000000..2e5a09e
--- /dev/null
+++ b/src/api/hello-body.zig
@@ -0,0 +1,20 @@
+const http = @import("http");
+const Context = http.handler.Context;
+const Response = http.Response;
+
+const Ctx = Context(.{"hello-body"});
+pub const ctx: Ctx = .{
+ .post = post,
+};
+
+const Body = struct {
+ value: usize,
+};
+
+fn post(request: Ctx.Request) Response {
+ const body = request.json(Body) catch return .bad_request(.void);
+
+ return .ok_or_error(.json(request.arena, .{
+ .value = body.value,
+ }));
+}
diff --git a/src/api/hello-json.zig b/src/api/hello-json.zig
new file mode 100644
index 0000000..7c96c29
--- /dev/null
+++ b/src/api/hello-json.zig
@@ -0,0 +1,15 @@
+const http = @import("http");
+const Context = http.handler.Context;
+const Response = http.Response;
+
+const Ctx = Context(.{ "hello-json" });
+pub const ctx: Ctx = .{
+ .get = get,
+};
+
+fn get(request: Ctx.Request) Response {
+ return .ok_or_error(.json(request.arena, .{
+ .value = 42,
+ .message = "Hello, Json!",
+ }));
+}
diff --git a/src/api/hello-param.zig b/src/api/hello-param.zig
new file mode 100644
index 0000000..ba798af
--- /dev/null
+++ b/src/api/hello-param.zig
@@ -0,0 +1,14 @@
+const http = @import("http");
+const Context = http.handler.Context;
+const Response = http.Response;
+
+const Ctx = Context(.{ "hello-param", .value });
+pub const ctx: Ctx = .{
+ .get = get,
+};
+
+fn get(request: Ctx.Request) Response {
+ const value = request.params.value.as(usize) catch return .bad_request(.string("parameter needs to be an int"));
+
+ return .ok_or_error(.json(request.arena, .{ .value = value, }));
+}
diff --git a/src/api/root.zig b/src/api/root.zig
index 7acd953..7570a76 100644
--- a/src/api/root.zig
+++ b/src/api/root.zig
@@ -6,7 +6,22 @@ const std = @import("std");
const http = @import("http");
const Interface = http.handler.Interface;
-pub const interfaces: []const Interface = &.{};
+const modules = .{
+ @import("hello-json.zig"),
+ @import("hello-param.zig"),
+ @import("hello-body.zig"),
+};
+
+pub const interfaces: []const Interface = ifs: {
+ var ifs: []const Interface = &.{};
+
+ for (modules) |module| {
+ const interface: []const Interface = &.{ module.ctx.interface() };
+ ifs = ifs ++ interface;
+ }
+
+ break :ifs ifs;
+};
test {
_ = std.testing.refAllDecls(@This());
diff --git a/src/http/Response.zig b/src/http/Response.zig
index 8d10992..d54792b 100644
--- a/src/http/Response.zig
+++ b/src/http/Response.zig
@@ -5,6 +5,15 @@ pub const Message = union(enum) {
static: []const u8,
streaming: std.Io.File,
+ pub fn json(arena: std.mem.Allocator, value: anytype) !Message {
+ var allocating: std.Io.Writer.Allocating = .init(arena);
+
+ var jsonify: std.json.Stringify = .{ .writer = &allocating.writer };
+ try jsonify.write(value);
+
+ return .string(try allocating.toOwnedSlice());
+ }
+
pub fn string(content: []const u8) Message {
return .{ .static = content };
}
@@ -27,6 +36,14 @@ pub fn ok(message: Message) @This() {
return with(.ok, message);
}
+pub fn ok_or_error(message: anyerror!Message) @This() {
+ return ok(message catch return with(.internal_server_error, .void));
+}
+
+pub fn bad_request(message: Message) @This() {
+ return with(.bad_request, message);
+}
+
pub fn send(
self: *const @This(),
io: std.Io,