Fundamentals of NEST.js
Tags: node, typescript, nest, nestjs
Published: 2021-10-02 18:46:21


Hi there, this is PART 0 of my NEST.js series. In this chapter I will explain the fundamentals of NEST.js, what it is and explain a bit of how it is structured. 
Therefore we use the provided CLI to create a brand new project. Afterwards we are going through each generated file and what purpose it has.

# What is NEST.js?
Here is what the official [documentation ](https://docs.nestjs.com/) says.

> Nest (NestJS) is a framework for **building efficient, scalable** **[Node.js](https://nodejs.org/)** **server-side applications*
>  Under the hood, Nest makes use of robust HTTP Server frameworks like [**Express**](https://expressjs.com/) (the default) and optionally can be configured to use [**Fastify*(https://github.com/fastify/fastify) as well!

So this means, that a lot of smart people put much effort in building on top of express (or fastify) a set of pre-built **capabilities** like logging or validation. This is great, because you dont have to built this by yourself, which means that you can focus on what matters, the business logic. Futhermore you can still use node libaries that you are used to, which is awesome, the best of both.
> Nest provides a level of abstraction above these common Node.js frameworks (Express/Fastify), but also exposes their APIs directly to the developer. This gives developers the freedom to use the myriad ofthird-party modules which are available for the underlying platform.

## Your first NEST.js project

We start by installing the CLI provided by NEST
`npm i -g @nestjs/cli`

We use the CLI to create a new project

    nest new demo_project
    
This creates a couple of files.

 - `app.controller.ts`  A basic controller with a single route.
 - `app.controller.spec.ts` The unit tests for the controller.
 - `app.module.ts` The root module of the application.
 - `app.service.ts` A basic service with a single method.
 - `main.ts` The entry file of the application

### main.ts - the starting point
```typescript
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
```

To create a Nest application instance, we use the core `NestFactory` class. `NestFactory` exposes a few static methods that allow creating an application instance. The `create()` method returns an application object, which will be assigned to the app variable. Afterwards we call the `listen` function to start the application and pass the port number (3000) as an parameter.  Run the command to start the application.

    npm run start

Once the application is running, open your browser and navigate to `http://localhost:3000/`. You should see the `Hello World!` message. Congratz, you just launched your first NEST.js backend 

### app.module.ts - The root module of the application
In NEST.js you structure your code as modules. You know this from React/Vue/Angular, where you create components. It is the same idea, but a module in NEST.js is a bit more abstract, because it can contains multiple controllers or services. Just remember, **functionalitiy** that belongs to the **same application domain**  it's wrapped with a **module**.

> Each application has at least one module, a **root module**. The root module is the starting point Nest uses to build the **application graph** - the internal data structure Nest uses to resolve module and provider relationships and dependencies.
![](https://docs.nestjs.com/assets/Modules_1.png)

In the app.module.ts we register all modules that are used in the application. So if we create a new module called users (using the CLI) 

    nest generate module users
Make sure it is defined in the **imports** section of the app.module.ts
```typescript
import { Module } from '@nestjs/common'
import { UsersModule } from './users/users.module'
import { AppController } from './app.controller'
import { AppImports } from './app.imports'
import { AppService } from './app.service'

@Module({

imports: [
UsersModule,
],
controllers: [AppController, HealthController],
providers: [AppService, TypegooseHealthIndicator],
})
export class AppModule {}
```

### app.controller.ts -  A basic controller with a single route
In general, a [controller](https://docs.nestjs.com/controllers#controllers) is responsible for handling incoming requests. In addition the controller also does input validation. If you have business logic or resuable functionality, we outsource this in a service class (which we will discuss later).  The service class is provided by a dependency injection. 
NEST is using [decorators](https://refactoring.guru/design-patterns/decorator) a lot. In order to tell NEST that we want to make a file to an controller, we use the `@Controller()` decorator above the class definition.
```typescript
import { Controller, Get } from  '@nestjs/common';
import { AppService } from  './app.service';

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

// reachable at localhost:3000/
@Get()
getHello():  string {
return  this.appService.getHello();
}
// reachable at localhost:3000/profile
@Get('profile')
getHello():  string {
return  this.appService.returnProfile();
}
-----------------------------------------------------------------
// make the controller accessible at localhost:3000/cats
@Controller('cats')
export  class  AppCatController {
constructor(private  readonly  appService:  AppService) {}

// reachable at localhost:3000/cats/profile
@Get('profile')
getHello():  string {
return  this.appService.returnProfile();
}
```
Remember the *Hello World* when you navigated to localhost:3000? The `getHello()` Function was responsible for that. Above the `getHello()`function you see another Decorator, `@Get()` , which is responsible for handling the GET Requests. What about the other HTTP request methods? Well clearly NEST provides them as well

`@Get()`,  `@Post()`,  `@Put()`,  `@Delete()`,  `@Patch()`,  `@Options()`, and  `@Head()`. In addition,  `@All()`  defines an endpoint that handles all of them.

Check out the code example above to learn more about the [routes](https://docs.nestjs.com/controllers#request-object).

### app.service.ts - A basic service with a single method.
A service (declared with the `@Injectable()` decorator) will be responsible for data storage and retrieval or business logic, and is designed to be used by the Controller, so it's a good candidate to be defined as a provider. Providers are a fundamental concept in Nest. Many of the basic Nest classes may be treated as a provider – services, repositories, factories, helpers, and so on. The main idea of a provider is that it can be  **injected**  as dependency; this means objects can create various relationships with each other, and the function of "wiring up" instances of objects can largely be delegated to the Nest runtime system.
```typescript 
import { Injectable } from  '@nestjs/common';
@Injectable()
export  class  AppService {

getHello():  string {
	return  'Hello World!';
	}
}
```
### app.controller.spec.ts - The unit tests for the controller.

How do you assume that your controller is working the way it should? Well NEST also handles this for us. If we create a new module with the CLI, NEST automatically adds a .spec file, a file, where we can define tests. NEST is using [JEST](https://jestjs.io/) and [Supertest](https://www.npmjs.com/package/supertest) frameworks for this purpose. 
```typescript 
import { Test, TestingModule } from  '@nestjs/testing';
import { AppController } from  './app.controller';
import { AppService } from  './app.service';

describe('AppController', () => {

let  appController:  AppController;

beforeEach(async () => {

const  app:  TestingModule  =  await  Test.createTestingModule({

controllers: [AppController],

providers: [AppService],

}).compile();

appController  =  app.get<AppController>(AppController);

});

describe('root', () => {

it('should return "Hello World!"', () => {

	expect(appController.getHello()).toBe('Hello World!');
});
 }); });
```
Whats happening here? In JEST there are HOOKS like in React. `beforeEach` is on of these Hooks. It is called before each test. There an app object is being created like in the main.ts file. From there we can access the Controller we want to test, in this case, the AppController.  In JEST we group multiple tests with `describe()`. As an first parameter we pass a string, defining the group, as an second, we pass an anonymous function. Inside we make use of the `it()` function. With the `it()` function we define a specific test. Like the `describe()` function, the first parameter is used to describe the test, the second an anonymous function to write the test logic. There we make use the `expect()` func, where we basically check if the `getHello()` function from the controller is returning 'Hello World'.
Go to console and type:

    npm run test
![jest successful tests](https://i.ibb.co/vqvwkC6/Unbenannt.jpg)
JEST will run our test (.spec) files. Yep, everything working as expected, nice. If you want to learn more about JEST and how to write tests, check out the [documentation](https://docs.nestjs.com/fundamentals/testing#testing).

## Summary 
Lets finish this section with a picture. It illustrates a Module, which is responsible for the user handling in our backend. It shows the tasks and the relationships between the different parts we discussed.

![Relationship between Module, Controller, Service in NEST:js](https://i.ibb.co/jwdGy1c/NESTJS-drawio-2.png)

## Lessons learned

- NEST.js is built on top of  (express/fastify) with batteries included, but offers you the freedom to use node related libaries

- A module wraps functionality that belongs to each other. With this approach, you automatically organize your code in an effective way.

- Use Controllers for input validation and request handling, use Services for business logic or ORM related stuff and write tests to make sure that everything works as expected

- Register your modules in the import section of the root module (`app.module.ts`) in order to use them 
- Everything in NEST that is uses the `@Injectable()` decorator, is a [provider](https://docs.nestjs.com/providers) in the NEST universum