- Add stdlib/http.lux with:
- Response builders (httpOk, httpNotFound, etc.)
- Path pattern matching with parameter extraction
- JSON construction helpers (jsonStr, jsonNum, jsonObj, etc.)
- Add examples/http_api.lux demonstrating a complete REST API
- Add examples/http_router.lux showing the routing pattern
- Update stdlib/lib.lux to include http module
The framework provides functional building blocks for web apps:
- Route matching: pathMatches("/users/:id", path)
- Path params: getPathSegment(path, 1)
- Response building: httpOk(jsonObj(...))
Note: Due to current type system limitations with type aliases
and function types, the framework uses inline types rather
than abstract Request/Response types.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
99 lines
3.5 KiB
Plaintext
99 lines
3.5 KiB
Plaintext
// HTTP Router Example
|
|
//
|
|
// Demonstrates the HTTP helper library with:
|
|
// - Path pattern matching
|
|
// - Response builders
|
|
// - JSON helpers
|
|
//
|
|
// Run with: lux examples/http_router.lux
|
|
// Test with:
|
|
// curl http://localhost:8080/
|
|
// curl http://localhost:8080/users
|
|
// curl http://localhost:8080/users/42
|
|
|
|
import stdlib/http
|
|
|
|
// ============================================================
|
|
// Route Handlers
|
|
// ============================================================
|
|
|
|
fn indexHandler(): { status: Int, body: String } =
|
|
httpOk("Welcome to Lux HTTP Framework!")
|
|
|
|
fn listUsersHandler(): { status: Int, body: String } = {
|
|
let user1 = jsonObject(jsonJoin([jsonNumber("id", 1), jsonString("name", "Alice")]))
|
|
let user2 = jsonObject(jsonJoin([jsonNumber("id", 2), jsonString("name", "Bob")]))
|
|
let users = jsonArray(jsonJoin([user1, user2]))
|
|
httpOk(users)
|
|
}
|
|
|
|
fn getUserHandler(path: String): { status: Int, body: String } = {
|
|
match getPathSegment(path, 1) {
|
|
Some(id) => {
|
|
let body = jsonObject(jsonJoin([jsonString("id", id), jsonString("name", "User " + id)]))
|
|
httpOk(body)
|
|
},
|
|
None => httpNotFound(jsonErrorMsg("User ID required"))
|
|
}
|
|
}
|
|
|
|
fn healthHandler(): { status: Int, body: String } =
|
|
httpOk(jsonObject(jsonString("status", "healthy")))
|
|
|
|
// ============================================================
|
|
// Router
|
|
// ============================================================
|
|
|
|
fn router(method: String, path: String, body: String): { status: Int, body: String } = {
|
|
if method == "GET" && path == "/" then indexHandler()
|
|
else if method == "GET" && path == "/health" then healthHandler()
|
|
else if method == "GET" && path == "/users" then listUsersHandler()
|
|
else if method == "GET" && pathMatches(path, "/users/:id") then getUserHandler(path)
|
|
else httpNotFound(jsonErrorMsg("Not found: " + path))
|
|
}
|
|
|
|
// ============================================================
|
|
// Server
|
|
// ============================================================
|
|
|
|
fn serveLoop(remaining: Int): Unit with {Console, HttpServer} = {
|
|
if remaining <= 0 then {
|
|
Console.print("Max requests reached, stopping server.")
|
|
HttpServer.stop()
|
|
} else {
|
|
let req = HttpServer.accept()
|
|
Console.print(req.method + " " + req.path)
|
|
let resp = router(req.method, req.path, req.body)
|
|
HttpServer.respond(resp.status, resp.body)
|
|
serveLoop(remaining - 1)
|
|
}
|
|
}
|
|
|
|
fn main(): Unit with {Console, HttpServer} = {
|
|
let port = 8080
|
|
let maxRequests = 10
|
|
Console.print("========================================")
|
|
Console.print(" Lux HTTP Router Demo")
|
|
Console.print("========================================")
|
|
Console.print("")
|
|
Console.print("Endpoints:")
|
|
Console.print(" GET / - Welcome message")
|
|
Console.print(" GET /health - Health check")
|
|
Console.print(" GET /users - List all users")
|
|
Console.print(" GET /users/:id - Get user by ID")
|
|
Console.print("")
|
|
Console.print("Try:")
|
|
Console.print(" curl http://localhost:8080/")
|
|
Console.print(" curl http://localhost:8080/users")
|
|
Console.print(" curl http://localhost:8080/users/42")
|
|
Console.print("")
|
|
Console.print("Starting server on port " + toString(port) + "...")
|
|
Console.print("Will handle " + toString(maxRequests) + " requests then stop.")
|
|
Console.print("")
|
|
HttpServer.listen(port)
|
|
Console.print("Server listening!")
|
|
serveLoop(maxRequests)
|
|
}
|
|
|
|
let output = run main() with {}
|