100 lines
2.4 KiB
Zig
100 lines
2.4 KiB
Zig
const std = @import("std");
|
|
const zzz = @import("zzz");
|
|
const tardy = @import("tardy");
|
|
const _dispatchers = @import("dispatchers.zig");
|
|
const log = std.log.scoped(.@"pgmql/http");
|
|
|
|
/// HTTP API server structure.
|
|
pub const Server = struct {
|
|
const Self = @This();
|
|
|
|
const Tardy = tardy.Tardy(.auto);
|
|
const Http = zzz.HTTP.Server(.plain);
|
|
const Router = Http.Router;
|
|
const Route = Http.Route;
|
|
const Context = Http.Context;
|
|
|
|
allocator: std.mem.Allocator,
|
|
dispatchers: []const _dispatchers.Dispatcher,
|
|
|
|
/// Host to use.
|
|
host: []const u8 = "127.0.0.1",
|
|
|
|
/// Port to use.
|
|
port: u16 = 8122,
|
|
|
|
/// Tardy runtime, if initialized.
|
|
ta: ?Tardy = null,
|
|
|
|
/// HTTP router, if initialized.
|
|
router: ?Router = null,
|
|
|
|
/// Initialize a new HTTP API server.
|
|
pub fn init(allocator: std.mem.Allocator, dispatchers: []const _dispatchers.Dispatcher) Self {
|
|
return Self{
|
|
.allocator = allocator,
|
|
.dispatchers = dispatchers,
|
|
};
|
|
}
|
|
|
|
/// Deinitialize the HTTP API server.
|
|
pub fn deinit(self: *Self) void {
|
|
if (self.ta) |*_ta| {
|
|
_ta.deinit();
|
|
}
|
|
|
|
if (self.router) |*_router| {
|
|
_router.deinit();
|
|
}
|
|
}
|
|
|
|
/// Setup Tardy and ZZZ.
|
|
fn setup(self: *Self) !void {
|
|
self.ta = try Tardy.init(.{
|
|
.allocator = self.allocator,
|
|
.threading = .auto,
|
|
});
|
|
|
|
self.router = Router.init(self.allocator);
|
|
|
|
// Set error JSON response.
|
|
//TODO Improve zzz to allow this.
|
|
|
|
// Set not found JSON response.
|
|
self.router.?.serve_not_found(Route.init().get({}, struct {
|
|
fn f(context: *Context, _: void) !void {
|
|
// Return a "not found" error as JSON.
|
|
try context.respond(.{
|
|
.status = zzz.HTTP.Status.@"Not Found",
|
|
.body = "{\"error\": \"not found\"}",
|
|
.mime = zzz.HTTP.Mime.JSON,
|
|
});
|
|
}
|
|
}.f));
|
|
}
|
|
|
|
/// Add API endpoints for the given dispatchers.
|
|
fn addApi(self: *Self) !void {
|
|
for (self.dispatchers) |dispatcher| {
|
|
// Add an endpoint of each dispatcher.
|
|
_ = dispatcher;
|
|
}
|
|
}
|
|
|
|
/// Start the HTTP API server.
|
|
pub fn start(self: *Self) !void {
|
|
try self.setup();
|
|
|
|
try self.ta.?.entry(
|
|
self, struct { fn f(runtime: *tardy.Runtime, server: *const Server) !void {
|
|
// Start a new HTTP server with the provided configuration.
|
|
var http = Http.init(runtime.allocator, .{});
|
|
try http.bind(.{ .ip = .{ .host = server.host, .port = server.port } });
|
|
try http.serve(&server.router.?, runtime);
|
|
} }.f,
|
|
{}, struct { fn f(runtime: *tardy.Runtime, _: void) !void {
|
|
try Http.clean(runtime);
|
|
} }.f
|
|
);
|
|
}
|
|
};
|