DEV Community

Cover image for 🐺 REST APIs with Elysia.js 🌿
James Robert Lund III
James Robert Lund III

Posted on • Edited on

🐺 REST APIs with Elysia.js 🌿


Hey API Dev, tired of building express apps that don't perform well under high loads? Want something that feels a bit cleaner and modern to build your next multi-million dollar project?

You may have heard of Bun, the newest JS runtime before, but have you heard of an ergonomic developer-friendly API framework that uses Bun?

If not, this article is for you 🎉

There's a few contenders out there but the one that really stood out to me is Elysia.

 

What is Elysia?

Elysia is a HTTP API framework written on Bun with developer experience being the main motivation of the framework.

Essentially, a faster Express.js replacement.

Elysia is set up for you to write functions and returns for your API. Need to send a response to the client? Just return your data in the callback function. No need to rely on req/res explicitly.

A basic Elysia endpoint could look like this:

Code snippet of a simple Elysia endpoint

Which will return a 200 and the string Test inside the response body.

The implementation syntax looks similar to express but cleaner, in my opinion.

 

Elysia Paths

You can leverage all the regular HTTP Methods and also add your own:

Code snippet showing API paths in Elysia

Or if you don't care about the method, you can use .all instead of .get .post etc.

You can also handle 404 errors like so:

Code snippet showing how to handle 404 errors in Elysia

Need dynamic paths? No worries:

Code snippet describing how to use dynamic paths in Elysia

Need multiple dynamic variables on an endpoint? They got you:

Code snippet of how to use dynamic variables in an endpoint

What about wildcards? Don't worry about it:

Code snippet showing how to use wildcards in Elysia

As you can see, Elysia has a lot of power baked in. But what about returning data?

 

Elysia's Handler Function

Those callbacks you saw in the code-snippets are the "handler". A handler is a callback function as the second argument in an endpoint. As you saw, we can extract params, path, and the request context by destructuring the request object:

Code snippet on how to descructure the request object in HTTP requests

The request object isn't lost to us tho. To alter request headers or redirects, we can leverage set like so:

Code snippet showing how to use the request object in Elysia

More info on request context here.

 

Elysia Responses

Elysia will automatically create the response object for you from whatever you return in your handler function.

If you want, you can also return a new Response() object and Elysia will handle it.

Want to move your routes to different files? Leverage Elysia's plugin system.

Need some additional functionality? Checkout the community.

 

Life Cycle Events

I won't go into too much detail here but this is an illustration of what's going on under the hood.

Elysia Life cycle diagram

When a request is made and accepted, the system will transform the request to the object we receive in our handler function.

If we have validation in place, that occurs next. The handler function is executed and returns data in form of a HTTP Response.

If this all makes sense, let's move on to a demo!
 

Makes sense meme

 

API Demo

💻 Completed code here

Let's start by creating a new Elysia app!

You can easily create a new Elysia app by running bun create elysia app in your terminal where "app" is the name of your new application. If you don't have Bun installed, you can install it via curl curl -fsSL https://bun.sh/install | bash.

Next, cd into the new directory and run the app with bun run dev. A dev server should start up at localhost:3000.

 

Building Our Endpoints

For this demo, we're going to be connecting to the Trefle plant API. This API contains a very wide variety of plants and we'll be performing get requests for the purpose of this demo.

We're going to make a few endpoints to get our plant data.

1. Get 30 plants
2. Search by query
3. Search by plant genus
4. Search by plant species
Enter fullscreen mode Exit fullscreen mode

First off, we'll add those endpoints to index.ts

Code snippet showing endpoints in our API application

Don't worry about the handler function for now, we'll add those later after we complete the next step.

Next, let's create the file that'll contain these functions in src/api.ts. Add these functions below:

Code snippet showing basic functions for handlers

But before we can attach these functions to the plant API, we need to get a token to authenticate. If you create an account here, you'll be granted with an API token to use their API.

Once you get your token, add it to .env inside our project as API_TOKEN. We'll leverage Bun to securely access our secrets. No dotenv package needed! Env variables are available via Bun with Bun.env.${YOUR_ENV}.

After your token has been added, let's kill the current server and restart with bun run dev. Now our value for the env variable should be accessible.

Next we will connect our API to Trefle with a generate URL function. This function will construct a new URL object and dynamically append any query params to the string.

Code snippet of generateUrl function to construct Trefle fetch url

Now that we have a way to construct our url to the Trefle API, let's start getting some data. We'll need to complete those handler functions I mentioned earlier.

For each handler, call the generateUrl function we created. For the specifics on getting plants, refer to the screenshot below. The purpose of this article isn't to use the Trefle API, just to demonstrate how to setup an Elysia instance.

Code snippet of finished code in src/api.ts file

Cool, if your code looks similar to the snippet above, let's move on to wrapping up the endpoints inindex.ts.

We just need to import the handler functions and assign them to the proper endpoints.

Code snippet of finished endpoints

After that's done, if we go to localhost:3000/plants in our browser, we should see a JSON object returned with 30 plants 🎉 🌿

Test out the other endpoints to get specific genus or species data! That about sums up the demo.

 

Additional Things About Elysia

There's still a lot about the framework that we couldn't cover in this article. Here are some quick links if anything catches your eye.

Cookies in Elysia
Swagger docs
Websockets
Lazy loading
Dos and donts
E2E type safety

 

Resources / Thank you

Thanks for taking the time to read! What did you think? Are you going to be trying Elysia anytime soon? Let me know in the comments!

If you want to know more about the API framework, checkout these links below.

Elysia Docs
Elysia Github
Official Plugins
Demo Repo

Image credits go to the Elysia repository image author. I did not create the banner image on this post

Top comments (5)

Collapse
 
tylerjrbuell profile image
Tyler Buell • Edited

Great article, I will be keeping Elysia in mind when building out my next web app! The fact that they have a companion front-end app Eden to go along with your server is super neat. It's like a built-in SDK that changes with your API 🤯

Collapse
 
jackkeller profile image
Jack Keller

Your Demo Repo is 404.

Collapse
 
lundjrl profile image
James Robert Lund III

fixed 👍

Collapse
 
hongquan profile image
Nguyễn Hồng Quân

Which tool you used for drawing diagram?

Collapse
 
lundjrl profile image
James Robert Lund III

Hey friend, I'm not sure. I got it from Elysia's documentation