Core Concepts
Request & Response
Understanding the CanxRequest and CanxResponse objects for handling HTTP communication.
Request Object
The CanxRequest object wraps the native Bun Request with additional helpers.
| Property | Type | Description |
|---|---|---|
| method | string | HTTP method |
| path | string | URL path |
| params | object | Route parameters |
| query | object | Query parameters |
| id | string | Unique request ID |
| timestamp | number | Request timestamp |
request-properties.ts
1app.get("/users/:id", async (req, res) => {2// Request properties3const method = req.method; // "GET"4const path = req.path; // "/users/123"5const id = req.id; // "canx_abc123" (unique request ID)6const timestamp = req.timestamp; // 170531280000078// Route parameters9const userId = req.params.id; // "123"1011// Query parameters (from ?key=value)12const page = req.query.page; // "1"13const limit = req.query.limit; // "10"1415// Headers16const auth = req.header("authorization");17const contentType = req.header("content-type");1819// Cookies20const session = req.cookie("session_id");2122return res.json({ userId, page, limit });23});
Reading Request Body
request-body.ts
1app.post("/users", async (req, res) => {2// Generic body parsing (auto-detects content type)3const data = await req.body();45// Typed body parsing6interface CreateUser { name: string; email: string; }7const user = await req.body<CreateUser>();89return res.json({ created: user });10});1112app.post("/form", async (req, res) => {13// Form data (multipart/form-data)14const formData = await req.formData();1516// Uploaded files17const files = await req.files();18const avatar = files.get("avatar");1920return res.json({ success: true });21});2223app.post("/raw", async (req, res) => {24// Raw text25const text = await req.text();2627// ArrayBuffer28const buffer = await req.arrayBuffer();2930return res.json({ length: text.length });31});
Request Context
Store and retrieve data throughout the request lifecycle.
context.ts
1// Store data in request context2const authMiddleware = async (req, res, next) => {3const user = await verifyToken(req.header("authorization"));4req.context.set("user", user);5req.context.set("authenticated", true);6return next();7};89// Access context data in handler10app.get("/profile", authMiddleware, (req, res) => {11const user = req.context.get("user");12const isAuth = req.context.get("authenticated");13return res.json({ user, isAuth });14});
Response Object
The CanxResponse provides a fluent API for building responses.
json-response.ts
1app.get("/api/users", (req, res) => {2// Basic JSON response (200)3return res.json({ users: [] });4});56app.post("/api/users", async (req, res) => {7const user = await createUser(await req.body());89// JSON with status code10return res.status(201).json({11message: "User created",12data: user13});14});1516app.get("/api/error", (req, res) => {17// Error response18return res.status(404).json({19error: "Not found",20code: "RESOURCE_NOT_FOUND"21});22});
HTML & Text Responses
html-response.ts
1app.get("/page", (req, res) => {2return res.html(`3<!DOCTYPE html>4<html>5<head><title>Hello</title></head>6<body><h1>Hello CanxJS!</h1></body>7</html>8`);9});1011app.get("/text", (req, res) => {12return res.text("Plain text response");13});1415app.get("/empty", (req, res) => {16return res.empty(204); // No content17});
Setting Headers
headers.ts
1app.get("/api/data", (req, res) => {2return res3.status(200)4.header("X-Request-Id", req.id)5.header("Cache-Control", "max-age=3600")6.headers({7"X-Custom-Header": "value",8"X-Another": "value2"9})10.json({ data: "example" });11});
Cookies
cookies.ts
1app.post("/login", async (req, res) => {2const { username, password } = await req.body();3const token = await authenticate(username, password);45// Set cookie with options6return res7.cookie("session", token, {8httpOnly: true,9secure: true,10sameSite: "Strict",11maxAge: 86400, // 1 day in seconds12path: "/"13})14.json({ success: true });15});1617app.post("/logout", (req, res) => {18// Clear cookie19return res.clearCookie("session").json({ loggedOut: true });20});
File & Stream Responses
files.ts
1app.get("/download/:filename", async (req, res) => {2const path = `./uploads/${req.params.filename}`;34// Send file (inline)5return res.file(path);6});78app.get("/export", async (req, res) => {9// Download with custom filename10return res.download("./data/report.pdf", "monthly-report.pdf");11});1213app.get("/stream", (req, res) => {14const stream = createReadableStream();15return res.stream(stream);16});
Server-Sent Events
sse.ts
1app.get("/events", (req, res) => {2async function* generateEvents() {3for (let i = 0; i < 10; i++) {4yield JSON.stringify({ count: i, time: Date.now() });5await new Promise(r => setTimeout(r, 1000));6}7}89return res.sse(generateEvents());10});
Redirects
redirect.ts
1app.get("/old-page", (req, res) => {2return res.redirect("/new-page"); // 302 default3});45app.get("/moved", (req, res) => {6return res.redirect("/new-url", 301); // Permanent redirect7});