// =============================================================================
// Boko Example App — demonstrates the framework API
// =============================================================================
module Main {
import Std::Io::{PrintLine, Print};
import Std::String::{String_Eq};
import Boko::{
App, App_New, App_Run,
Request, Response,
Request_GetQuery, Request_GetPathParam,
Response_Html, Response_Json, Response_NotFound, Response_Redirect,
Path_Match,
HttpVerb
};
extern func bux_strlen(s: String) -> uint;
extern func bux_sb_new(initial_cap: uint) -> *void;
extern func bux_sb_append(sb: *void, s: String);
extern func bux_sb_build(sb: *void) -> String;
extern func bux_sb_free(sb: *void);
// =============================================================================
// Boko_Router — user-defined dispatch (called by the framework)
// =============================================================================
func Boko_Router(req: Request) -> Response {
// --- GET / ---
if String_Eq(req.path, "/") && req.method.tag == HttpVerb_GET {
return Response_Html(PageHome());
}
// --- GET /api/health ---
if String_Eq(req.path, "/api/health") {
return Response_Json("{\"status\":\"ok\",\"framework\":\"Boko\",\"version\":\"0.1.0\"}");
}
// --- GET /api/info ---
if String_Eq(req.path, "/api/info") {
return Response_Json("{\"name\":\"Boko\",\"language\":\"Bux\",\"inspiration\":\"FastAPI\",\"features\":[\"routing\",\"path-params\",\"query-params\",\"json\"]}");
}
// --- GET /hello?name=World ---
if String_Eq(req.path, "/hello") {
let name: String = Request_GetQuery(&req, "name");
if bux_strlen(name) == 0 { name = "World"; }
let sb: *void = bux_sb_new(256);
bux_sb_append(sb, "
Hello, ");
bux_sb_append(sb, name);
bux_sb_append(sb, "!
");
let html: String = bux_sb_build(sb);
bux_sb_free(sb);
return Response_Html(html);
}
// --- GET /users/{id} ---
if Path_Match("/users/{id}", req.path, &req) {
let id: String = Request_GetPathParam(&req, "id");
let sb: *void = bux_sb_new(128);
bux_sb_append(sb, "{\"id\":");
bux_sb_append(sb, id);
bux_sb_append(sb, ",\"name\":\"User ");
bux_sb_append(sb, id);
bux_sb_append(sb, "\"}");
let json: String = bux_sb_build(sb);
bux_sb_free(sb);
return Response_Json(json);
}
// --- GET /posts/{postId}/comments/{commentId} ---
if Path_Match("/posts/{postId}/comments/{commentId}", req.path, &req) {
let pid: String = Request_GetPathParam(&req, "postId");
let cid: String = Request_GetPathParam(&req, "commentId");
let sb: *void = bux_sb_new(128);
bux_sb_append(sb, "{\"postId\":");
bux_sb_append(sb, pid);
bux_sb_append(sb, ",\"commentId\":");
bux_sb_append(sb, cid);
bux_sb_append(sb, ",\"text\":\"Great post!\"}");
let json: String = bux_sb_build(sb);
bux_sb_free(sb);
return Response_Json(json);
}
// --- GET /redirect → 302 to / ---
if String_Eq(req.path, "/redirect") {
return Response_Redirect("/");
}
// --- POST /api/echo ---
if String_Eq(req.path, "/api/echo") && req.method.tag == HttpVerb_POST {
let sb: *void = bux_sb_new(256);
bux_sb_append(sb, "{\"echo\":");
bux_sb_append(sb, req.body);
bux_sb_append(sb, "}");
let json: String = bux_sb_build(sb);
bux_sb_free(sb);
return Response_Json(json);
}
// --- 404 ---
return Response_NotFound();
}
// =============================================================================
// HTML landing page (raw multi-line string via backticks)
// =============================================================================
func PageHome() -> String {
return `
Boko Framework
⚡ Boko
Async web framework for Bux — inspired by FastAPI
Try it
Features
✓Path routing with {params}
✓Query parameter extraction
✓JSON / HTML / Text responses
✓Multi-threaded (configurable)
✓Redirects (302)
✓POST body access
`;
}
// =============================================================================
// Main — start the server
// =============================================================================
func Main() -> int {
let app: App = App_New(8080, 4);
App_Run(&app);
return 0;
}
} // module Main