How to Design REST APIs Using Express, MongoDB, and TypeScript.

Nishant
The Startup
Published in
5 min readJan 23, 2021

In this tutorial, we are going to talk about how to design REST Services in TypeScript, MongoDB, and Express.

Prerequisites:

  1. NPM or Yarn package Manager
  2. Express
  3. TypeScript
  4. Postman
  5. MongoDB and Mongoose.
  6. REST Services for TypeScript

Project Layout:

In our Project, we are going to create endpoints that will create, retrieve and update using POST, GET and PUT methods. To achieve this goal, we will be using Mongoose functions like create(), findOne(), findOneAndUpdate()

The endpoints will be created in Express.

Installing Dependencies:

  1. First of all, install Node(if you haven’t) and NPM or Yarn Package Manager. This will be used to install dependencies on your machine.
  2. Once it has been installed, install Express using npm install express @types/express --save-dev.
  3. You’ll also need MongoDB and Mongoose. Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node.js. It manages relationships between data, provides schema validation, and is used to translate between objects in code and the representation of those objects in MongoDB. Get MongoDB from https://docs.mongodb.com/guides/server/install/ and install Mongoose using npm install mongoose --save.
  4. Postman, to send and receive API requests. Install it from https://www.postman.com/downloads/
  5. TypeScript is an open-source language that builds on JavaScript, one of the world’s most used tools, by adding static type definitions. Types provide a way to describe the shape of an object, providing better documentation, and allowing TypeScript to validate that your code is working correctly. Install TypeScript using npm install typescript -g.
  6. Last, but not least, install the TypeScript REST package from https://www.npmjs.com/package/typescript-rest. This is a lightweight package to write endpoints and paths using Typescript.

Package.json

Type npm init to initialize the project. This will ask you the name of your project, it’s author, version, GIT repository link, license, and all. You can skip them for now using npm init -y command.

Once the basic installation is complete, add a few scripts to the package.json file.

"scripts": {
"watch-ts": "tsc -w",
"watch-node": "nodemon dist/server.js",
"watch": "concurrently -k -p \"[{name}]\" -n \"TypeScript, Node\" -c \"yello.bold, cyan.bold\" \"yarn run watch-ts\" \"yarn run watch-node\""
}

Your package.json now looks something like this.

{
"name": <Your Project Name>,
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"watch-ts": "tsc -w",
"watch-node": "nodemon dist/server.js",
"watch": "concurrently -k -p \"[{name}]\" -n \"TypeScript, Node\" -c \"yello.bold, cyan.bold\" \"yarn run watch-ts\" \"yarn run watch-node\""
},
"dependencies": {
"@types/express": "^4.11.1",
"concurrently": "^3.5.1",
"express": "^4.16.3"
}
}

Tsconfig.json

Create a new tsconfig.json file within your root directory and add the following configuration:

{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": false,
"target": "es6",
"noImplicitAny": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"baseUrl": ".",
"paths": {
"*": ["node_modules/", "src/types/*"]
}
},
"include": ["src/**/*"]
}

Your app.ts file

Create your app.ts file and add the following code into it.

import * as express from "express";
import {Server, Path, GET, PathParam} from "typescript-rest";

class Sample {
@Path("/hello:name")
@GET
sayHello( @PathParam('name') name: string ): string {
return "Hello " + name;
}}
let app: express.Application = express();
Server.buildServices(app);
app.listen(3000, function() {
console.log('Rest Server listening on port 3000!');
});

Call the API using http://localhost:3000/hello/Nishant.

Connecting to MongoDB:

Create a file db.ts and add the following code to it. This block of code contains the local address of your database.

import * as mongoose from 'mongoose';export class myDB {public static async initDB() {
return mongoose.connect('mongodb://localhost:27017/local');
}
public static async closeCon() {
return mongoose.connection.close(true);
}}

Import this file in your app.ts and initialize it in your constructor.

import * as express from "express";
import { myDB } from './db';
import {Server, Path, GET, PathParam} from "typescript-rest";
class Sample {constructor(){
myDB.initDB();
}
let app: express.Application = express();
Server.buildServices(app);
app.listen(3000, function() {
console.log('Rest Server listening on port 3000!');
});

Creating Models:

Let’s create a folder called models. Create a file userModel inside the models' folder.

import * as mongoose from 'mongoose';
import { Model } from 'mongoose';
type UserType = UserModel & mongoose.Document;export interface UserModel {
firstname:{
type: String,
required: true
}
lastname:{
type: String,
required: true
}
mobile: {
type: Number
}
age: {
type: Number,
}
pincode: {
type: Number
}
};
const Users = new mongoose.Schema({
firstname:{
type: String,
required: true
},
lastname:{
type: String,
required: true
},
mobile: {
type: Number
},
age: {
type: Number,
},
pincode: {
type: Number
},
});
const Users: Model<UserType> = mongoose.model<UserType>('Users', UserSchema,'Users');export default Users;

This model will be used to create the interface and the schema in the Mongo database.

Let’s import this file into our main app.ts. These imports will be used later while creating API bodies i.e. POST, GET and PUT.

import * as express from "express";
import { myDB } from './db';
import Users, { UserModel } from './models/userModel';
import {Server, Path, GET, PathParam} from "typescript-rest";
class Sample {constructor(){
myDB.initDB();
}
let app: express.Application = express();
Server.buildServices(app);
app.listen(3000, function() {
console.log('Rest Server listening on port 3000!');
});

Your database setup is now complete.

Making POST Requests:

import * as express from "express";
import { myDB } from './db';
import Users, { UserModel } from './models/userModel';
import {Server, Path, POST } from "typescript-rest";
class ExampleClass{constructor(){
myDB.initDB();
}
@POST
@Path('post/users')
public async createUser(newRecord: UserModel){
try{
var users = await Users.create(newRecord);
return users;
}catch(e){
console.log(e);
}};
let app: express.Application = express();
Server.buildServices(app);
app.listen(3000, function() {
console.log('Rest Server listening on port 3000!');
});

Here, createUser method takes UserModel as a parameter and returns the record in the Postman body.

{
“firstname”: “Nishant”,
“lastname”: “Kumar”,
“mobile”: 123456789,
“age”: 24,
“pincode”: 987654
}

Put the address above as http://localhost:3000/post/users.

You’ll get something like:

[{
"_id":<Some Random id>
“firstname”: “Nishant”,
“lastname”: “Kumar”,
“mobile”: 123456789,
“age”: 24,
“pincode”: 987654
}]

You have successfully made your POST request.

Similarly, you can make GET and PUT requests.

import * as express from "express";
import { myDB } from './db’;
import Users, { UserModel } from './models/userModel’;
import {Server, Path, POST, GET, PUT, PathParam} from "typescript-rest";
import { ObjectId } from "mongodb";
class ExampleClass{constructor(){
myDB.initDB();
}
@POST
@Path('post/users')
public async createUser(newRecord: UserModel){
try{
var users = await Users.create(newRecord);
return users;
}catch(e){
console.log(e);
}};
@PUT
@Path('put/users/:id')
public async updateUser(@PathParam('id') id: ObjectId){
try{
var users = await Users.findOneAndUpdate({ _id: id });
return users;
}catch(e){
console.log(e);
}};
@GET
@Path('get/users/:id')
public async getUser(@PathParam('id') id: ObjectId){
try{
var users = await Users.findOne({ _id: id });
return users;
}catch(e){
console.log(e);
}};
let app: express.Application = express();
Server.buildServices(app);
app.listen(3000, function() {
console.log('Rest Server listening on port 3000!');
});

Your final app.ts file will look like this.

POST: http://localhost:3000/post/users

PUT: http://localhost:3000/put/users/:id

GET: http://localhost:3000/get/users/:id

That’s all. Try and experiment. Happy learning.

--

--