Discover Elysia: The Exciting New Framework for Building APIs with TypeScript
Recently, I discovered a fantastic new framework that leverages the Bun runtime, which boasts impressive performance improvements over traditional frameworks like NestJS and Express. This new framework not only streamlines development with its modern features but also delivers significantly faster response times and handles higher throughput with ease. If you’re looking for a cutting-edge solution that enhances both speed and efficiency, this framework might be exactly what you need to take your API development to the next level.
In this blog post, I’ll share what I’ve learned about connecting to a database and performing GET requests to explore some of Elysia’s features. By the end, you’ll understand why Elysia could become your new go-to tool for API development.
What is ElysiaJS
ElysiaJS is a cutting-edge API framework built to harness the power of Bun as its runtime environment. As the flagship API framework for Bun, ElysiaJS represents the forefront of innovation in web development, offering developers a modern toolset that integrates seamlessly with Bun’s high-performance capabilities.
Recently, ElysiaJS was officially released into production by X (formerly known as Twitter), marking a significant milestone in its development and adoption. This release underscores the framework’s robustness and reliability, making it a strong contender in the API development landscape.
Prerequisites
First, Elysia is a framework that runs on Bun, so let’s start by installing Bun.
For MacOS & Linux
curl -fsSL https://bun.sh/install | bash
For Windows
powershell -c "irm bun.sh/install.ps1 | iex"
Install Elysia and Set Up Your Project
Once you have Bun installed, setting up Elysia for your project is straightforward. In this example, we’ll use a Master API for managing Thai location addresses.
First, use Bun to create a new Elysia project by running:
bun create elysia address-api
This command initializes a new Elysia project named address-api
, setting up the basic project structure and files.
Then, move into the project folder
cd address-api
Since we will be using PostgreSQL with TypeORM for this project, you’ll need to add the appropriate dependencies. Install them using:
bun add @elysiajs/swagger pg typeorm
Additionally, for TypeScript type definitions, install the devDependencies:
bun add -D @types/pg
Run and Test Your Project
After setting up your project and installing the necessary dependencies, let’s run and test it first.
Use this command to start development server.
bun dev
Now, open browser or Postman to see the results at http://localhost:3000
Then let’s make a small change. Typically, APIs have /api
as a prefix (or /api/v1/
or else if you want), so let's add that prefix to our project.
const app = new Elysia({ prefix: "/api" })
.get("/", () => "Hello Elysia")
Now, our index.ts
should look like this:
Now if we run it again in Postman should be like this.
Swagger API
Elysiajs has the very easy way to add swagger API to the project. All we need to do is import Swagger:
import { swagger } from "@elysiajs/swagger";
Then update the code as follows
const app = new Elysia({ prefix: "/api" })
.use(swagger())
.get("/", () => "Hello Elysia");
Then, we can access it by opening http://localhost:3000/api/swagger. In this case, /api/swagger
is the path because we added the /api
prefix. By default, Swagger is accessible at /swagger
, but you can customize the path by adding the path
option inside swagger()
, like this:
.use(swagger({ path: '/custom-swagger-path' }))
The result should be like this.
Database Integration
Now, let’s set up the database connection. Create a new file called ./src/datasource.ts
and define it as follows. In this blog, we'll assume that you already have PostgreSQL set up and running. Feel free to setup and config it as yours.
Next, update your index.ts
file to include the database initialization:
async function initializeDatabase() {
try {
await myDataSource.initialize();
console.log("Database connection established");
} catch (error) {
console.error("Error connecting to the database", error);
}
}
initializeDatabase();
Now our index.ts
file should be like this.
Entities Setup
Next, let’s set up the entities. In TypeORM, the table structure definition is called an Entity. These entities define the structure of your database tables. Create the following files for your entities.
- Assuming you have created tables with the same names as specified in the
@Entity
decorators, these entities will map to your database tables correctly.
1. Province Entity
This entity defines a table named province
with columns for id
, name_th
, and name_en
.
2. District Entity
This entity defines a table named district
with columns for id
, name_th
, name_en
and province_id
for link with Province entity.
3. Subdistrict Entity
This entity defines a table named subdistrict
with columns for id
, name_th
, name_en
, zip_code
and district_id
for link with District entity.
Next, to inform TypeORM that these files are entities for the database, add them to datasource.ts
so that datasource.ts
will look like this:
Controllers
Now, move to the controller section. Create the file ./src/controllers/location.ts
and add the following code:
This locationController
provides methods to fetch and sort data related to provinces, districts, and subdistricts from your database.
provinces
: Retrieves a list of all provinces ordered by their Thai names.districtsByProvinceId
: Retrieves a list of districts for a given province, ordered by their Thai names.subdistrictsByDistrictId
: Retrieves a list of subdistricts for a given district, ordered by their Thai names.
Routes
Now, the last section: routes
Let’s create ./src/routes/location.ts
as follows:
Include all things to the App
Let’s add our route into the app in index.ts like follows
app.use(Locations);
so our index.ts should be like this
Let’s run and check our API
Now let’s check the swagger, it could be automatically updated right now.
Check some routes
Conclusion
Elysia offers an exciting and streamlined approach to building APIs with TypeScript. Its powered by Bun, support for Swagger documentation, and compatibility with PostgreSQL via TypeORM make it a compelling choice for modern API development. One of the standout features of Elysia is its impressive performance. Benchmark tests have shown that Elysia outperforms many traditional API frameworks, delivering faster response times and handling higher throughput with ease.
In our next blog, we’ll dive into creating, updating, and deleting requests, as well as explore performance optimizations and authentication strategies.
Happy coding! And have fun with Elysia.