Getting Started With NestJS
Tags: javascript, typescript, node
Published: 2022-07-25 18:09:26

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;

```bash
npm i -g @nestjs/cli
```

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 

```bash
nest new project-name
```

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;

```bash
npm i -g @nestjs/cli
nest new project_name
```

Alternatively you can clone the starter template git

```bash
git clone https://github.com/nestjs/typescript-starter.git project_name;
```

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

```bash
cd project_name;
npm install;
```

### 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.

```javascript

src/----------|------app.controller.ts
     |------app.service.ts
     |------app.module.ts
     |------main.ts
```

#### 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.

```typescript
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();
```

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`.

```typescript
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 {}
```

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.

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

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

```

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. 

```typescript
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();
  }
}

```

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;

```bash
npm start
``` 

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.