Bun Bakery
Bun-Bakery is a web framework for Bun. It uses a file based router in style like svelte-kit. No need to define routes during runtime.
Quick Start
bun add @kapsonfire/bun-bakery
On your main script import Router from bun-bakery and define your pathes. i.e. main.ts
import {Router} from "@kapsonfire/bun-bakery"
new Router({
assetsPath: import.meta.dir + '/assets/',
routesPath: import.meta.dir + '/routes/'
})
After that run the server and open your browser http://localhost:3000
bun main.ts
Routing
Routes are added automatically when creating files inside your routesPath
when exporting functions with the corresponding Method Names.
Given example above create index.ts
inside routes/
and export a GET
function calling ctx.sendResponse()
.
import {Context} from "@kapsonfire/bun-bakery"
export async function GET(ctx: Context) {
ctx.sendResponse(new Response('hello world!'));
}
Parameters
Routes can have parameters inside dirname and/or filename. Just put the parameter name inside brackets and it will be added to ctx.params
.
In example: given routes/user/[username].ts
and open http://localhost:3000/user/kapsonfire
import {Context} from "@kapsonfire/bun-bakery"
export async function GET(ctx: Context) {
ctx.sendResponse(new Response('hello '+ ctx.params.username +'!'));
}
will output hello kapsonfire!
Spread Paramaters
Routes can also have wildcard/spread paramaters.
In example: given routes/users/[...usernames].ts
and open http://localhost:3000/users/kapsonfire/jarred/tricked
import {Context} from "@kapsonfire/bun-bakery"
export async function GET(ctx: Context) {
ctx.json(JSON.stringify(ctx.params));
}
will output
{"usernames":["kapsonfire","jarred","tricked"]}
Websocket Server
Bun-Bakery supports websocket endpoint export for Bun.serve({...}).
Just export WEBSOCKET
as Object registering the websocket hooks.
In example: given routes/websocket/user.ts
export const WEBSOCKET = {
message: (ws, message) => {
console.log('RCV:', message);
ws.send('ECHO: ' + message);
},
upgrade: (ctx: Context) => {
ctx.acceptWebsocketUpgrade();
}
}
More detailed example:
export const WEBSOCKET = {
message: (ws, message) => {
console.log('RCV:', message);
ws.send('ECHO: ' + message);
},
upgrade: (ctx: Context) => {
ctx.acceptWebsocketUpgrade({
data: {
name: new URL(req.url).searchParams.get("name") || "Friend",
},
headers: {
'Set-Cookie': 'name=value'
}
});
}
}
This will accept Websocket Connections on `ws://localhost:3000/websocket/user
NOTE: Websocket Endpoints don't support params in the url.
Handlers
Inside the context variable you can access the native bun Request
object inside ctx.request
.
ctx.sendResponse
expects a native bun Response
object.
Middlewares
bun-bakery supports some life-cycles to add middleware
-
onRequest
will be called before the router handles the request
-
onRoute
will be called before the route function will be called
-
onResponse
will be called after the route function finished
router.addMiddleware({
onRequest: (ctx: Context) => { ctx.params.injected = "1"; console.log('onRequest', ctx) },
onRoute: (ctx: Context) => console.log('onRoute', ctx),
onResponse: (ctx: Context) => {
ctx.response.headers.set('content-type', 'application/jsonx');
console.log('onResponse', ctx)
},
});