In a previous tutorial, we talked about creating an express project using Typescript. It had some of the default routing features built into express and we were able to return JSON from different user requests. In this tutorial, we’ll rewrite that but will Typescript controllers. There is an awesome package called ‘routing-controllers‘ that helps to add this functionality to express. Please click here if you want to gain access to Typescript videos and ExpressJS courses.

Typescript Model

In the previous tutorial, we created a model called User. We were able to serialize this Model to JSON and display it when hitting our ‘/users’ route. We’re going to make a modification to that model and add an id field. It’ll be optional.

export default class User {
  id?: number;
  username: String;
  name: String;
  email: String;

  constructor(name: String, username: String, email: String, id?: number) {
    this.id = id;
    this.name = name;
    this.username = username;
    this.email = email;
  }

  getUsername() {
    return this.username;
  }
  getName() {
    return this.name;
  }
}

Adding Typescript Dependencies

The next step is to add the necessary dependencies to our project. We will add routing-controllers and reflect-metadata. Reflect-metadata allows us to use decorators in our typescript class and add augmented features to a class, it’s properties and it’s methods.

npm install --save reflect-metadata routing-controllers

We’ll also modify our server file to add routing-controllers.

import express from "express";
import bodyParser from "body-parser";
import "reflect-metadata";
import { useExpressServer } from "routing-controllers";

import { UserController } from './controllers/user';

const server = express();

server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: true }));

useExpressServer(server, {
  // register created express server in routing-controllers
  controllers: [UserController] // and configure it the way you need (controllers, validation, etc.)
});

server.listen(3000, function () {
    console.log('Example app listening on port 3000!')
});

You’ll see that I import UserController and place it in a controllers array.

Creating A Typescript Controller

To make sure that we can run REST requests, we’ll also need to create our UserController.ts file. Inside of that file, import routing-controllers as well as its decorators.

import { JsonController, OnUndefined, Param, Body, Get, Post, Put, Delete } from "routing-controllers";

You can see that JsonController specifies that a class is a controller that returns JSON. You also have decorators for the common HTTP requests and another decorator for what to do is an object is undefined and to get an error.

Once that is done, you can create your controller with all of you CRUD methods. There is a mock data store in this example to simulate some of these functions.

import { JsonController, OnUndefined, Param, Body, Get, Post, Put, Delete } from "routing-controllers";
import User from '../models/user';

@JsonController()
export class UserController {
  userStore: User[];

  constructor() {
    this.userStore = [
      new User("James Coonce", "jcoonce", "james@none.com", 1),
      new User("Jim Coonce", "jimcoonce", "jim@none.com", 2),
      new User("Norman", "jcoonce", "norman@none.com", 3)
    ];
  }
  @Get("/users")
  getAll() {
    return this.userStore;
  }

  @Get("/users/:id")
  @OnUndefined(404)
  getOne(@Param("id") id: number) {
    let users = [
      new User("James Coonce", "jcoonce", "james@none.com", 1),
      new User("Jim Coonce", "jimcoonce", "jim@none.com", 2),
      new User("Norman", "jcoonce", "norman@none.com", 3)
    ];

    let user = users.find(x => x.id === id);
    return user;
  }

  @Post("/users")
  post(@Body() user: any) {
    const newUser = new User(user.name, user.username, user.email);
    return newUser;
  }

  @Put("/users/:id")
  put(@Param("id") id: number, @Body() user: any) {
    let currentUser = this.userStore.find(x => x.id === id);
    if (currentUser != undefined) {
      currentUser.name = user.name;
      currentUser.username = user.username;
      currentUser.email = user.email;
      return currentUser;
    }

    return "No user found";
  }

  @Delete("/users/:id")
  remove(@Param("id") id: number) {
    return "Removing user...";
  }
}
Rest Typescript Node.JS Controller

Rest Typescript Node.JS Controller

Conclusion

Adding simple controller functionality to Typescript and ExpressJS is simple. You can use packages like routing-controllers or even frameworks like NestJS to build out more structured applications. Click here for more information as well as video courses on Node.JS development.

Codebrains Newsletter

Get weekly dev news and tutorials.

Powered by ConvertKit