How to build a CRUD API with Express.js and TypeScript

Racheal Kuranchie
6 min readApr 11, 2023

--

Photo by Clément Hélardot on Unsplash

In today’s digital world, APIs are the backbone of modern web applications, enabling seamless communication between client-side and server-side components. Among the most popular frameworks for building APIs, Express.js stands out for its simplicity, flexibility, and scalability. But why settle for a basic Express.js API when you can supercharge it with the power of TypeScript? In this tutorial, we’ll show you how to create a full-fledged CRUD (Create, Read, Update, Delete) API with Express.js and TypeScript, complete with data validation, and database integration. So fasten your seat belt and get ready to take your API development skills to the next level!

Mongoose will be the Object Document Mapper (ODM) that will be used to perform the logic while MongoDB will be used as our database and Joi for data validation.

Prerequisites

Before we start make sure you have node installed on your machine along with mongodb.

NB.

Visit the MongoDB atlas platform, signup, and create a cluster that will generate a connection string to be used for this application.

https://www.mongodb.com/docs/atlas/getting-started/ . Follow this link to guide you through the process of setting up your mongo atlas.

OR

Once you have mongodb installed locally, you can connect your database locally by first starting your mongodb server on the command line.

The connection string you get from starting the server looks like this "mongodb://localhost:27020/"

Project Setup

Start the Project by creating a new folder or directory to be used with this command step by step.

mkdir api //create a folder
cd api //change directory into the folder
npm init -y //initialize the application

This will create the package.json file which will be your center for all packages.

Package.json

After initializing the package.json, the next thing is to install the packages we will need for this application.

Packages for the application

Express.js , mongoose , mongodb , dotenv , typescript , nodemon, joi

npm install express dotenv mongoose mongodb joi 
npm install nodemon --save-dev

Once you have installed these, You will see a node modules and a package-lock.json files added to the package.json file. The next step is to install typescript as a dev dependency along with the types for the packages installed.

npm install typescript ts-node @types/node @types/express --save-dev

You will notice typescript-related dependencies are installed as devDependencies. This is because, though the code is written in Typescript, it will be compiled as ‘vanilla’ JavaScript.

Now to use typescript in your application, you would have to initialize it. For that, we would create the tsconfig.json file where we can customize the compiler options. We get this file by using this command.

npx tsc --init

The tsconfig.json file contains a lot of compiler options, most of which have been commented. Nevertheless, it can be customized to fit the specific needs of your application. Some of these options used in the config are very important which include:

  • target: Allows us to specify the target JavaScript version that the compiler will output.
  • module: Specify what module code is generated in the JavaScript code. CommonJS is supported and is a standard in Node.js
  • strict: An option that enables strict type-checking options
  • esModuleInterop: Allows us to compile ES6 modules to CommonJS modules
  • skipLibCheck: If set to true, skips type-checking of default library declaration files
  • forceConsistentCasingInFileNames: When set to true, enables case-sensitive file naming

One option that you will have to enable is called outDir, which specifies where the output will be located after the compilation step. NB. this is necessary because the typescript code needs to be compiled to Vanilla JavaScript. You can find this option in the /*Emit */ section in the tsconfig.json file and uncomment it.

  • By default, the value of this option is set to the root directory. Change it to dist folder:

Folder Structure

Time to create your folder structure. I like the separation of concerns by minimizing my code as much as I can. This helps in easy debugging and also makes your code readable and clean.

Create a src and dist folder. The dist folder will contain all your compiled code. In the src folder, create these folders: Controllers, Models, Routes, Services, Server, and Config. In these folders, create the following files: post.controller.ts, posts.ts, post.routes.ts, post.service.ts, app.ts, and db.config.ts, respectively.

Create a .env file in the root directory and keep your mongo DB atlas database username and password.

After installing and initializing typescript in your application, the next step is to edit the package.json file. Add the following to the scripts: start, dev and build.

The next stage is to connect your database to your application. In your db.config.ts in the config folder, write this code. With mongoose, we can get access to the mongoose.connect() method to connect to our database and communicate with it.

Server Connection

Now that we have connected our database, the next thing is to create our server and see if the database has indeed been connected. Creating a server in express.js is straightforward. You have to import express and initialize it by assigning a variable to it then you get access to all the HTTP methods to use. In other to pass a JSON body in your request, you have to use express methods like express.json().

To start the the application, run the following command.

npm run dev

Create the Schema and the Model

Go into your posts.ts in the model folder and create your schema and model with this code. The schema is a representation of the database tables which describes the types in your database, and the model is a design that decides what should be in the schema. The PostschemaValidate specifies the fields types needed in the request body in other to be saved. It serves as another layer of validation for the request.

Create the Service

After creating the model, the next step is to create the service class that will hold all the operations we want to perform. In the service class, we will create different functions that reads, create, update and delete a post using the mongoose queries like create, find, findById, etc.

Create the Controller

Now, in the controller, we will call each of the functions in the service and execute it. In order to make our code readable and clean, we keep each file as simple as we can and each function to have one responsibility in the application. The code is also easily maintainable and scalable as we have separated concerns so we can focus on each features.

Create the Route

The route is where we will use the HTTP ( POST, GET, PUT, DELETE ) etc. methods to perform the operations in the controller. We will create our endpoints according to each function.

Testing

Time to test your endpoints on postman or a REST Client.

Finally, check your data in the mongo database in the mongo atlas.

Mongo atlas

CONCLUSION

CHEERS !!!

You have created an API for creating, reading, updating and deleting data from the database. You can check my previous post on Authentication and Authorization.

This API can be found on GitHub for more reference. Thank you.

--

--

Racheal Kuranchie

Software Engineer || Fullstack Developer || React.js || Node.js || PostgreSQL