• +91 9790 650 659
  • This email address is being protected from spambots. You need JavaScript enabled to view it.
  • Setting Up Project

    Make sure that you have NodeJS and MongoDB installed on your machine. After that, you have to install TypeScript Node.

    npm install -g typescript ts-node

    In order to test HTTP request, we can use Postman to send sample requests.

    Step 1: Initiate a Node project

    Create a project folder and initiate the npm project. Remember to answer all the question, and you can edit it any time after that

    mkdir restful-webapi-with-node
    cd restful-webapi-with-node
    npm init

    Step 2: Install all the dependencies

    npm install --save @types/express express body-parser mongoose nodemon

    Step 3: Configure the TypeScript configuration file

    The idea is to put all the TypeScript files in the root folder with sub folders for development purpose, then for the production, we will save all the Javascript files in the dist folder. And of course, we will take advantage of the ES2015 in the project.

    // tsconfig.json
    {
    "compilerOptions": {
    "module": "commonjs",
    "moduleResolution": "node",
    "pretty": true,
    "sourceMap": true,
    "target": "es6",
    "outDir": "./dist",
    "baseUrl": "./"
    },
    "exclude": [
    "node_modules"
    ]
    }

    So whenever we run the tsc command, all the ts files in the lib folder will be compiled to js files in the dist folder

    tsc

    Step 4: edit the running scripts in package.json

    "scripts": {
    "build": "tsc",
    "dev": "ts-node ./server.ts",
    "start": "nodemon ./dist/server.js",
    "prod": "npm run build && npm run start"
    }

    So, for the development, we can run a test server by running

    npm run dev

    For production

    npm run prod

    Step 5: getting started with the base configuration

    You will need sooner or later the package body-parse for parsing incoming request data.

    // ./app.ts
    import * as express from "express";
    import * as bodyParser from "body-parser";

    class App {

    public app: express.Application;

    constructor() {
    this.app = express();
    this.config();
    }

    private config(): void{
    // support application/json type post data
    this.app.use(bodyParser.json());

    //support application/x-www-form-urlencoded post data
    this.app.use(bodyParser.urlencoded({ extended: false }));
    }
    }

    export default new App().app;

    Create ./server.ts file

    // ./server.ts
    import app from "./app";
    const PORT = 3000;

    app.listen(PORT, () => {
    console.log('Express server listening on port ' + PORT);
    })

    From now, although you can not send a HTTP request yet, you still can test the project by running npm run dev.

    Implement routing and CRUD

    Step 1: Create TS file for routing

    Remember in part 1 of this project. We save everything in the root folder for microservices. So I will create routes folder with a file named userRoutes.ts that will save all the routes for this project.

    // ./routes/userRoutes.ts
    import {Request, Response} from "express";

    export class Routes {
    public routes(app): void {
    app.route('/')
    .get((req: Request, res: Response) => {
    res.status(200).send({
    message: 'GET request successfulll!!'
    })
    })
    }
    }

    After creating our first route, we need to import it to the ./app.ts.

    // ./app.ts
    import * as express from "express";
    import * as bodyParser from "body-parser";
    import { UserRoutes } from "./routes/userRoutes";

    class App {

    public app: express.Application;
    public userRoutes: UserRoutes = new Routes();

    constructor() {
    this.app = express();
    this.config();
    this.userRoutes.routes(this.app);
    }

    private config(): void{
    this.app.use(bodyParser.json());
    this.app.use(bodyParser.urlencoded({ extended: false }));
    }
    }

    Now, you can send GET request to your application (http://localhost:3000) directly or by using Postman.

    Step 2: Building CRUD for the Web APIs

    I assume that you have a basic understanding of HTTP request (GET, POST, PUT and DELETE). If you don’t, it is very simple:

    • GET: for retrieving data
    • POST: for creating new data
    • PUT: for updating data
    • DELETE: for deleting data

    Now we will build the routing for building a user CRM that saves, retrieves, updates and deletes user info.

    // ./routes/userRoutes.ts
    import {Request, Response} from "express";

    export class Routes {

    public routes(app): void {

    app.route('/')
    .get((req: Request, res: Response) => {
    res.status(200).send({
    message: 'GET request successfulll!!!!'
    })
    })

    // User
    app.route('/user')
    // GET endpoint
    .get((req: Request, res: Response) => {
    // Get all users
    res.status(200).send({
    message: 'GET request successfulll!!'
    })
    })
    // POST endpoint
    .post((req: Request, res: Response) => {
    // Create new user
    res.status(200).send({
    message: 'POST request successfulll!!'
    })
    })

    // User detail
    app.route('/user/:userId')
    // get specific user
    .get((req: Request, res: Response) => {
    // Get a user information
    res.status(200).send({
    message: 'GET request successfulll!!'
    })
    })
    .put((req: Request, res: Response) => {
    // Update a user
    res.status(200).send({
    message: 'PUT request successfulll!!'
    })
    })
    .delete((req: Request, res: Response) => {
    // Delete a user
    res.status(200).send({
    message: 'DELETE request successfulll!!'
    })
    })
    }
    }

    Now the routes are ready for getting HTTP request.

    Using Controller and Model for Web APIs

    Step 1: Create Model for your data

    All the model files will be saved in ./models folder. We will define the structure of the User by using Schema from Mongoose.

    //   ./models/userModel.ts
    import * as mongoose from 'mongoose';

    const Schema = mongoose.Schema;

    export const UserSchema = new Schema({
    firstName: {
    type: String,
    required: 'Enter a first name',
    },
    lastName: {
    type: String,
    required: 'Enter a last name',
    },
    email: {
    type: String,
    },
    company: {
    type: String,
    },
    phone: {
    type: Number
    },
    created_date: {
    type: Date,
    default: Date.now,
    },
    });

    This model will be used inside the controller where we will create the data.

    Step 2: Create your first Controller

    Remember we have created CRUD place holder for communicating with the server. Now we will apply the real logic to the route and controller.

    1. Create a new user (GET request)

    All the logic will be saved in the ./controllers/userController.ts

    //   ./controllers/userController.ts
    import * as mongoose from 'mongoose';
    import { UserSchema } from './models/userModel';
    import { Request, Response } from 'express';

    const User= mongoose.model('User', UserSchema);
    export class UserController{
    ...
    public addNewUser (req: Request, res: Response) {                
    const user= new User(req.body);

    user.save((err, user) => {
    if(err){
    res.send(err);
    }
    res.json(user);
    });
    }

    In the route, we don’t have to pass anything.


    // ./routes/userRoutes.ts
    import { UserController } from "./controllers/userController";
    public userController: UserController = new UserController();
    // Create a new user
    app.route('/user')
    .post(this.userController.addNewUser);

    2. Get all users (GET request)

    All the logic will be saved in the ./controllers/userController.ts

    //   ./controllers/userController.ts
    ...
    public getUsers (req: Request, res: Response) {           
    User.find({}, (err, users) => {
    if(err){
    res.send(err);
    }
    res.json(users);
    });
    }
    }

    After that, we will import UserController and apply getUsers method.

    // ./routes/userRoutes.ts
    // Get all Users
    app.route('/users')
    .get(this.userController.getUsers)

    3. View a single user (GET method)

    We need the ID of the user in order to view the user info.

    //   ./controllers/userController.ts
    public getUser (req: Request, res: Response) {           
    User.findById(req.params.userId, (err, user) => {
    if(err){
    res.send(err);
    }
    res.json(user);
    });
    }

    In the routes, we simply pass the ‘/user/:userId’

    // ./routes/userRoutes.ts
    // get a specific user
    app.route('/user/:userId')
    .get(this.userController.getUserWithID)

    4. Update a single user (PUT method)

    Remember that, without {new: true}, the updated document will not be returned.

    //   ./controllers/userController.ts
    public updateUser (req: Request, res: Response) {           
    User.findOneAndUpdate({ _id: req.params.userId }, req.body, { new: true }, (err, user) => {
    if(err){
    res.send(err);
    }
    res.json(user);
    });
    }

    In the routes,

    // ./routes/userRoutes.ts
    // update a specific user
    app.route('/user/:userId')
    .put(this.userController.updateUser)

    5. Delete a single user (DELETE method)

    //   ./controllers/userController.ts
    public deleteUser (req: Request, res: Response) {           
    User.remove({ _id: req.params.userId }, (err, user) => {
    if(err){
    res.send(err);
    }
    res.json({ message: 'Successfully deleted user!'});
    });
    }

    In the routes,

    // ./routes/userRoutes.ts
    // delete a specific user
    app.route('/user/:userId')
    .delete(this.userController.deleteUser)

    * Remember that you don’t have to call app.route(‘/user/:userId’) every single time for GET, PUT or DELETE a single user. You can combine them

    // ./routes/userRoutes.ts
    app.route('/user/:userId')
    // edit specific user
    .get(this.userController.getUser)
    .put(this.userController.updateUser)
    .delete(this.userController.deleteUser)

    From now, your model and controller are ready. 

    You can enjoy referring the code which is written by me for Restful Web API's with Node, Express, Typescript and MongoDB.

    Github URL: https://github.com/ranjithprabhuk/Restful-web-api-with-node-express-mongo-and-typescript

    Thanks for reading.