@kakengloh/bagel
v0.2.2
Published
Tiny and expressive web framework for Bun.js
Downloads
10
Maintainers
Readme
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