How to develop REST APIs using Express.js and Typescript?
Taking look at managed and distributed code structure for developing APIs.
In this article, we will be taking a look at how we can develop REST API in Node.js. The important thing we will be understanding is the code structure, management, and distribution of code logic into different modules. For this purpose, I have created an npm package that you can use as a starter kit to initialize your project using Express, Typescript, and integrated with Prisma for DB purposes. I am assuming that if you are here reading this blog, you already know about the following:
- Already have at least the latest version of Node.js (LTS) and npm installed in your system.
- Know about the essentials of developing Rest APIs, if not visit the following Twitter threads:
๐งต What does an HTTP request include?
๐งต Structure of a URL
Initializing the project
Let's start by initializing the project, for that purpose I have created a starter kit with the folder structure, I use for developing the rest APIs. You can initiate your project by using the following npm command:
npx create-express-ts-api <project-name>
npm install
Tech Stack Used
- Node.js
- Typescript
- Express.js
- Prisma (as ORM)
Understanding the folder structure
Note: In each directory, we are using barrel files for better export-import utility over the project.
- routes: This directory includes all the router-related logic.
- controllers: This directory contains all the main controllers or request handlers, these handlers will be called or used for their respective requests in the routes folder.
- models: In this directory, we have two sub-dir: API: This includes all the external API integration, encapsulated in classes. Factory: This includes all our database queries distributed in factories for each entity in the DB.
- prisma: This is a default directory created by prisma used for storing schema in schema.prisma and the DB migrations
- database: it contains the docker file for the development database.
Setting up Development DB
In my development environment, I generally use, docker containers to set up my development database. By default, the project has integration with PostgreSQL, if you wanna change it, do change the service in database/docker-compose.yml.
- To set up the development DB make sure you have docker and docker-compose installed in your system.
- Add a .env file at the root of the project and add a Database URL in the file, as per the service defined in docker-compose the DB URL will be the following:
PORT=3000
DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb"
- You can run the following command to trigger the development DB setup.
npm run dev:db
npm run db-generate
Defining routes and controllers:
Routes
In express, we can create routers, and then either we can use middleware to pass on the request to a further specified route, or we can grab the request on the current path only, by defining the request method on the router object only. Let's see in the code:
Here you can see two things:
I am using router.use(), because I want to specify the further path of the request as well in the other files. It means the URL for this request will look like: <base-url>/v1/.....
But router.get(), means that the path of the request ends here, and the path will look like <base-url>/
.
In the same way, further classification of the route has been done using router. Let's take one more example:
- In my own API, a request
<base-url>/v1/twitter/tweet/:id
look like this, but it has been divided in the following manner in the folder structure. - entry point handles
<base-url>/
- src/routes/index.ts - handles path till
`<base-url>/v1/
- src/routes/v1/index.ts - handles path till
<base-url>/v1/twitter/
- src/routes/v1/twitter.ts defines the final path.
Controllers
For each path we have a different file defined for the subsequent controllers and all the controller functions are encapsulated in classes. For middleware controllers such auth middleware to check if the user is authenticated or not, you can add those in src/middlewares.
Start the server
You can run the following command to start the server.
npm run dev
Your API must be accessible on the port you defined (mostly 3000).
If in any case you face any bug or issue you can reach out to me at the socials given below.
Do share the blog, if it helped you. โจโจ