DEV Community 👩‍💻👨‍💻

DEV Community 👩‍💻👨‍💻 is a community of 963,274 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for Getting Started With NestJS
Kinanee Samson
Kinanee Samson

Posted on

Getting Started With NestJS

NestJS a JavaScript framework that can be used to build scalable and dynamic server side applications very quickly and easily, NestJS is built with TypesScript and supports TypeScript out of the box, it feels very much like using Angular but on the backend, you see the project was heavily influenced by Angular. NestJS enforces a certain application structure and this is one of the benefits of using NestJS.

NestJS combines the best of OOP and functional programming, it also exploits the benefits of using TypeScript. It is built upon some popular libraries that we use to build NodeJS server side applications like Express and Cors. NestJS is a high level abstraction that is built on these simple libraries, so much thought has been put into the framework development and some of the obvious benefit that comes from using the framework includes;

  • Reduction of unnecesary code
  • Fast development time
  • Ease with testing apps

No matter how cool we say JavaScript really is, there are some pitfalls that comes with using JavaScript, especially for server side apps. There is often the problem of file and module structure, lack of types, there's often too much duplicated code, and it is quite difficult to test your app, all these are problems familiar to some developers and the goal of using NestJS is to provide an elegant solution to all these problems.

Nest JS was built to give projects a certain level of structure, most often junior developers struggle with choosing the right project structure, handling application dependencies and other third party plugins. NestJS is the right tool for the junior developer, or anyone who has trouble adopting a particular application structure. It is also a good solution to the afore mentioned problems. NestJS also makes it incredibly easy for us to test our applications.

Installation

To install NestJS you have to ensure that you have NodeJS installed on your PC, then you can run;

npm i -g @nestjs/cli
Enter fullscreen mode Exit fullscreen mode

This installs the very capable NestJS CLI that comes baked in with some commands that can allows us to spin up new projects and lots of other utility features we will need when building applications with NestJS.
We can scaffold a new nestjs project by running

nest new project-name
Enter fullscreen mode Exit fullscreen mode

This will scaffold a project for us with some basic code, you can now proceed to opening up the project in your favorite text editor. The two commands we just ran are;

npm i -g @nestjs/cli
nest new project_name
Enter fullscreen mode Exit fullscreen mode

Alternatively you can clone the starter template git

git clone https://github.com/nestjs/typescript-starter.git project_name;
Enter fullscreen mode Exit fullscreen mode

Navigate into the newly created folder, and install the dependencies.

cd project_name;
npm install;
Enter fullscreen mode Exit fullscreen mode

Folder Structure

A NestJS project will often posses the following folder structure depending on which version you are using, as of the time of this writing, NestJS is in version 9.0.5. We will only concern ourselves with the src folder, that's going to be the only folder we will be working with most of the time. That's where our application source code will be stored.


src/----------|------app.controller.ts
     |------app.service.ts
     |------app.module.ts
     |------main.ts
Enter fullscreen mode Exit fullscreen mode

main.ts

This file contains the file necessary code for bootstrapping and starting our application. It imports NestFactory and the main module for our application, creates a server app for us and listens on a specified port for an incoming request.

import { NestFactory } from  '@nestjs/core';
import { AppModule } from  './app.module';

async  function  bootstrap() {
 const  app  =  await  NestFactory.create(AppModule);
 await  app.listen(3000, () =>  console.log(`App started on PORT 3000`));
}

bootstrap();
Enter fullscreen mode Exit fullscreen mode

Calling the create() method of NestFactory builds a http application for us from the application main module, The app that is returned by this method satisfies the NestExpressApplication interface and this interface exposes some useful methods for us. We start the http server by calling app.listen() as we would have with an express app. If it isn't apparent, you now see the benefit of working with NestJS, enabling CORS on our application is as simple as calling app.enableCors() on our application. Ordinarily it would require us to first install cors module and then using it as a middleware. To create our http app/server we need to pass in our applications main module as an argument to the create method of NestFactory, we would look at the app.module.ts below.

app.module.ts

A module in NestJS is simply a data structure for managing our applications dependencies. Modules are used by Nest to organize the application structure into scopes. Controllers and Providers are scoped by the module they are declared in. Modules and their classes (Controllers and Providers) form a graph that determines how Nest performs, for a class to serve as a NestJS module it should be decorated with the @Module() decorator. Let's examine the contents of the app.module.ts.

import { Module } from '@nestjs/common';
import { AppController } from './app.controller.ts';
import { AppService } from './app.service.ts';

@Module({
 imports: [],
 controllers: [AppController],
 providers: [AppService]
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

The imports array is responsible for handling other modules that this module depends on, as our application grows we would have other modules because NestJS suggests that each feature in application should have it's own module, rather than polluting the global module namespace. The imports array handles those other modules. The controllers array handles the contorllers that we create in our application, while the providers array handles services that we create in our application. The module class also scopes the controllers and providers, making them available only in the module they are registered with. We are going to have a brief overview of contorllers and services.

app.service.ts

A service in NestJS is similar in concept to a service in Angular, a service is just a class that encapsulates helper methods in our application, we define functions that helps get certain things done, in this example we define only one method on app.service.ts which returns hello world! Another name for a service is a provider. Let's inspect our app.service.ts file.

import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}

Enter fullscreen mode Exit fullscreen mode

For a class to serve provider it should be decorated with the @Injectable which is exported by @nestjs/common, we can proceed to declaring methods on the class that we use in our code.

app.controller.ts

A controller is a just another fancy name for a route handler, a controller will define a method that is usually attached to a route, whenever there is a request to the server that matches a particular route, the controller will call the function that is attached to the route.

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

Enter fullscreen mode Exit fullscreen mode

We already established that NestJs makes use of dependency injection, in the above controller we inject the AppService provider so we can use the methods declared on it. For a class to serve as a controller it should be decorated with the @Controller decorator as demonstrated above, the decorator can accept a string as an argument, that string will serve as a base route for that controller. Http verbs can be applied as decorators to the functions that will process an incoming request. In the above example, a @Get decorator which matches to the http verb GET is applied to the getHello function. Thus whenever there is a GET request to the server, the getHello function is called as the handler to that route.

The decorators that serve as http verbs also accepts strings as argument and they serve as a secondary path to match after the one defined in the @Controller. In the above example, the base route is / because no argument is passed into the @Contorller decorator and the route for the @Get controller is also / because no argument is also passed to the @Get decorator attached to the getHello function that is why a request made to the server http://localhost:3000/ will return hello world.

Starting the app

To kick start the server, we simply run;

npm start
Enter fullscreen mode Exit fullscreen mode

The NestJS CLI which you have access to if installed with npm i @nestjs/cli will bootstrap and start the application for us in production mode. To start the server in development mode, which enables hot reload we can run npm i start:dev and any changes we make while the server is running locally will take effect.

In fututre articles in this series we will take our time to explore NestJS providers, controllers, modules and lots of other features of NestJS, that is it for today, i hope you enjoyed this and i hope you found this useful, please leave your comment down below about what your thoughts or experience on using NestJS, feel free to add in anything you feel i left out in this introduction in the comments.

Top comments (0)

"I made 10x faster JSON.stringify() functions, even type safe"

☝️ Must read for JS devs