@kakengloh/bagel
    TypeScript icon, indicating that this package has built-in type declarations

    0.2.0 • Public • Published

    Bagel.js logo Bagel

    Bagel is a tiny and expressive web framework for Bun.js for building web APIs.

    Inspired by Express.js and Koa.js.

    Here we treat Typescript as first class citizen, hence every request handler supports generic and you may specify your own typing of request params, query, body and response body.

    Contents

    Features

    Routing

    Middlewares

    JSON parsing

    Strongly typed route handlers

    Installation

    bun add @kakengloh/bagel

    Examples

    Basic

    import { Bagel, Router } from '@kakengloh/bagel';
    
    const app = new Bagel();
    
    app.get('/', async (req, res) => res.send('Hello from Bagel.js!'));
    
    app.listen(3000);

    Router

    import { Bagel, Router } from '@kakengloh/bagel';
    
    // Create items router
    const items = new Router();
    items.get('/', async (req, res) => res.json({ items: [] }));
    
    // Create v1 router
    const v1 = new Router();
    // Mount items router to v1 router
    v1.mount('/items', items);
    
    const app = new Bagel();
    
    // Mount v1 router to app
    app.mount('/v1', v1);
    
    app.listen(3000);

    Middleware

    import { Bagel, Router } from '@kakengloh/bagel';
    
    const app = new Bagel();
    
    // Before middleware
    app.use(async (req, res, next) => {
      console.log('Before');
    });
    
    // Route handler
    app.get('/', async (req, res) => res.send('Hello from Bagel.js!'));
    
    // After middleware
    app.use(async (req, res, next) => {
      console.log('After');
    });
    
    app.listen(3000);

    Strong typing

    import { Bagel, Handler } from '@kakengloh/bagel';
    
    // Entity
    interface Bread {
      bakeryId: string;
      name: string;
      price: number;
    }
    
    // Path parameters
    interface PathParams {
      bakeryId: string;
    }
    
    // Query parameters
    type QueryParams = Record<string, unknown>;
    
    // Request body
    type RequestBody = Bread;
    
    // Response body
    interface ResponseBody {
      bread: Bread;
    }
    
    // Route handler with all types specified
    const createBread: Handler<
      PathParams,
      QueryParams,
      RequestBody,
      ResponseBody
    > = async (req, res) => {
      const { name, price } = req.body; // Typed inferred
      const { bakeryId } = req.params; // Typed inferred
    
      const bread: Bread = {
        bakeryId,
        name,
        price,
      };
    
      return res.json({ bread }); // Typed checked
    };
    
    const app = new Bagel();
    app.post('/bakeries/:bakeryId/breads', createBread);
    
    app.listen(3000);

    Error handling

    import { Bagel } from '@kakengloh/bagel';
    
    const app = new Bagel({
      // Every error thrown will go through this function
      // Here you can return a custom response
      error: async (res, err) => {
        return res.status(400).json({ error: 'Bad request' });
      },
    });
    
    app.get('/error', async () => {
      throw new Error('Some error');
    });
    
    app.listen(3000);

    Benchmark

    Below is a simple benchmark of Bagel.js and Express.js conducted on my machine using autocannon (12 threads, 500 concurrent connections, 10 seconds)

    The output shows that Bagel.js can handle ~2.67x more requests than Express.js

    Screenshot 2022-09-09 at 9 19 02 PM

    Screenshot 2022-09-09 at 9 15 42 PM

    Install

    npm i @kakengloh/bagel

    DownloadsWeekly Downloads

    11

    Version

    0.2.0

    License

    MIT

    Unpacked Size

    160 kB

    Total Files

    47

    Last publish

    Collaborators

    • kakengloh