Bunary is v0.x and under active development — APIs may still move between minor releases.

    Routing

    Define your application's routes and endpoints.

    Basic Routing

    Bunary provides a simple and expressive API for defining routes. The most basic routes accept a path and a handler function:

    import { createApp } from "@bunary/http";
    
    const app = createApp();
    
    app.get("/", () => {
      return { message: "Hello, World!" };
    });
    
    app.listen({ port: 3000 });
    

    You can pass options to createApp({ basePath?, onNotFound?, onMethodNotAllowed?, onError? }) (e.g. basePath: "/api" to prefix all routes). See the @bunary/http package docs for full options. HEAD requests use GET routes automatically; OPTIONS returns allowed methods.

    Available HTTP Methods

    The router supports the following HTTP methods:

    app.get("/users", handler);
    app.post("/users", handler);
    app.put("/users/:id", handler);
    app.patch("/users/:id", handler);
    app.delete("/users/:id", handler);
    

    Route Handlers

    Route handlers receive a context object and can return various response types:

    // Return JSON object (automatically serialized)
    app.get("/json", () => {
      return { status: "ok" };
    });
    
    // Return with custom status using Response
    app.post("/users", () => {
      return new Response(JSON.stringify({ id: 1, name: "John" }), {
        status: 201,
        headers: { "Content-Type": "application/json" },
      });
    });
    
    // Return plain text
    app.get("/text", () => {
      return new Response("Hello, World!", {
        headers: { "Content-Type": "text/plain" },
      });
    });
    
    // Async handlers
    app.get("/async", async () => {
      const data = await fetchData();
      return data;
    });
    

    Query Parameters

    Access query string parameters via the context. The query property is a URLSearchParams object:

    // GET /search?q=bunary&limit=10
    app.get("/search", (ctx) => {
      const query = ctx.query.get("q");
      const limit = ctx.query.get("limit") || "20";
      
      return { query, limit: parseInt(limit) };
    });
    

    The Request Context

    Every route handler receives a RequestContext object with the following properties:

    PropertyTypeDescription
    requestRequestThe native Fetch API Request object
    paramsRecord<string, string | undefined>URL route parameters (optional params may be undefined)
    queryURLSearchParamsQuery string parameters
    localsRecord<string, unknown>Per-request data (e.g. ctx.locals.auth from auth middleware)

    Accessing Request Data

    Use the native Request object methods to access request data:

    app.post("/users", async (ctx) => {
      // Access request method
      const method = ctx.request.method;
      
      // Access request URL
      const url = new URL(ctx.request.url);
      
      // Access headers
      const contentType = ctx.request.headers.get("Content-Type");
      
      // Parse JSON body
      const body = await ctx.request.json();
      
      return { received: body };
    });
    

    Last updated