DEV Community

Vau
Vau

Posted on

Write a express like api using bunjs

I came across Youtube to find some interesting tech videos, then I found a video talking about Bun, which is a javascript runtime written in Zig. It introduces itself as an incredibly fast runtime, way more faster than Nodejs.

So I decided to take a try…

I take a look at the http server api from Bun.

Here is how to download bun in command line



curl -fsSL https://bun.sh/install | bash


Enter fullscreen mode Exit fullscreen mode

Here is the first way, if the js file export a default object with fetch function in it, it will start the server.

Inside indexjs



export default {
  fetch(req) {
    return new Response("HI!");
  },
};


Enter fullscreen mode Exit fullscreen mode

Or you can use Bun.serve



Bun.serve({
  fetch(req) {
    return new Response("HI!");
  },
});


Enter fullscreen mode Exit fullscreen mode

To start server, run bun run index.js

And that’s it ! Everything is working…

But this api is too down level, it means it needs developers to write duplicate code when project gets big. So I decided to make an express like api using bun from scratch, every one new to bun would no need to learn the bun api if they have experience on express.

Here is what I do.

First, we need to handle the request.

We create a BunServer class with http method in it.

Image description

Everything go through the http method will use delegate function to handle.

requestMap is store the map of path and its handler.

middlewares stores all the middlewares user declares

Image description
Above is the delegate function, which we store them in cache.

And that’s how we handler request, pretty simple.

Then it’s the middleware.

On express, we have middleware function with signature (req, res, next) , it’s a chain of responsibility design pattern. Here is how I implemented.

Image description

I created a Chain class to handle middlewares passing. Just a few things you need to know here.

  1. every next function is called, will do index++ , we get the callback function from middlewares with that index.
  2. Stop signal. To stop the middleware from passing, we check this.ready first, which user returns response from one of the middlewares. And this.isFinish() , we had already called all the middlewares.

Finally, we wrap things up on the fetch method on bun api.

Image description
When the request comes in, we first called all the middlewares first, if the middleware does not stop the request, we called the request handler, which we actually how to handle our business logic.

Here is how to use it.

The package is called bunrest, it’s already published on npm



npm i bunrest


Enter fullscreen mode Exit fullscreen mode

First create a server object



import App from 'bunrest'
const server = new App.BunServer();


Enter fullscreen mode Exit fullscreen mode

Then you can use it like on express.



server.get('/test', (req, res) => {
  res.status(200).json({ message: 'succeed' });
}, (req, res, next) => {
  console.log('get');
  next();
});
server.put('/test', (req, res) => {
  res.status(200).json({ message: 'succeed' });
}, (req, res, next) => {
  console.log('put');
});
server.post('/test', (req, res) => {
  res.status(200).json({ message: 'succeed' });
});


Enter fullscreen mode Exit fullscreen mode

Add middlewares



// or you can add the middlewares this way
server.get('/user', 
    (req, res) => { /** handle request **/ }, 
    (req, res, next) => {
      /**
       *  Handle middlewares
       * */
    });


Enter fullscreen mode Exit fullscreen mode

Add router



// add router
const router = server.Router();

router.get('/test', (req, res) => {
  res.status(200).json({ message: 'Router succeed' });
})

router.post('/test', (req, res) => {
  res.status(200).json({ message: 'Router succeed' });
})

router.put('/test', (req, res) => {
  res.status(200).json({ message: 'Router succeed' });
})

server.use('/your_route_path', router);


Enter fullscreen mode Exit fullscreen mode

Finally, to start the server



server.listen(3000, () => {
  console.log('App is listening on port 3000');
});


Enter fullscreen mode Exit fullscreen mode

If you want to checkout the source code or contribute, here is the github page

Top comments (3)

Collapse
 
link2twenty profile image
Andrew Bone

Hello!

If you'd like, you can add syntax highlighting (colors that make code easier to read) to your code block like the following example.

console.log('Hello world!');
Enter fullscreen mode Exit fullscreen mode

This should make it a bit easier to understand your code. 😎

In order to use this in your code blocks, you must designate the coding language you are using directly after the first three back-ticks. So in the example above, you'd write three back-ticks js (no space between the two), put the code beneath (e.g. console.log('Hello world!');), then three back-ticks beneath that to close the code.

Here's an image that shows how it's written!

Example of how to add syntax highlighting in code blocks

Collapse
 
lau1944 profile image
Vau

Thx for the tips!

Collapse
 
lundjrl profile image
James Robert Lund III

Working on my own Bun server for a side-project. Thanks for sharing!