07. September 2020
NestJS | Getting started – Part 1
Introduction
NestJS (just Nest from here on out), is a Node framework meant to build server-side applications. Not only is it a framework, but it is also a platform to meet many backend application needs, like writing APIs, building microservices, or doing real-time communications through web sockets.
Nest is also heavily influenced by Angular, and you will immediately find its concepts familiar. The creators of Nest strived to make the learning curve as small as possible, while still taking advantage of many higher level concepts such as modules, controllers, and dependency injection.
Installation
Install NodeJS
Download NodeJS from here and install as described here.
For example, on macOS using Homebrew
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="shell" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">brew install node
Or download the package
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">curl "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- https://nodejs.org/dist/latest/ | sed -nE 's|.*>node-(.*)\.pkg</a>.*|\1|p')}.pkg" > "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/"
Install NextJS
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="shell" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">npm i -g @nestjs/cli
Create server App
Create new server App
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="shell" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">nest new demo.server
Start server App
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="shell" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">cd demo.server
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="shell" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">npm run start:dev
Now open browser on http: localhost:3000
App Structure
main.ts
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
app.module.ts
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
app.controller.ts
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">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();
}
}
app.service.ts
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
Add Functionality
Create service and controller
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">nest g service missions
nest g controller missions
Modify mission service
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">@Injectable()
export class MissionsService {
missions: Mission[] = [
{ id: 1, title: 'Rescue cat stuck in asteroid', reward: 500, active: true, },
{ id: 2, title: 'Escort Royal Fleet', reward: 5000, active: true, },
{ id: 3, title: 'Pirates attacking the station', reward: 2500, active: false, },
];
async getMissions(): Promise<Mission[]> {
return this.missions;
}
}
Modify mission controller
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">@Controller('missions')
export class MissionsController {
constructor(private missionsService: MissionsService) {}
@Get()
getMissions() {
return this.missionsService.getMissions();
}
}
Open in browser: http://localhost:3000
Create new frontend App
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">ionic start demo.frontend sidemenu
Working with Database and TypeORM
Create / Sync database with schema
Add command to package.json
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="ini" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">"scripts": {
"typeorm": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js"
}
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">npm run typeorm schema:sync
TypeORM Commands
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">schema:sync
Synchronizes your entities with database schema. It runs schema update queries on all connections you have. To run update queries on a concrete connection use -c option.
schema:log
Shows sql to be executed by schema:sync command. It shows sql log only for your default connection. To run update queries on a concrete connection use -c option.
schema:drop
Drops all tables in the database on your default connection. To drop table of a concrete connection's database use -c option.
query
Executes given SQL query on a default connection. Specify connection name to run query on a specific connection.
entity:create
Generates a new entity.
subscriber:create
Generates a new subscriber.
migration:create
Creates a new migration file. [Aliase: migrations:create]
migration:generate Generates a new migration file with sql needs to be executed to update schema. [Aliase: migrations:generate]
migration:run
Runs all pending migrations. [Aliase: migrations:run]
migration:show
Show all migrations and whether they have been run or not
migration:revert
Reverts last executed migration. [Aliase: migrations:revert]
version
Prints TypeORM version this project uses.
cache:clear
Clears all data stored in query runner cache.
init
Generates initial TypeORM project structure. If name specified then creates files inside directory called as name. If its not specified then creates files inside current directory.
Additional readings
- Full-Stack TypeScript with Ionic, Angular, and NestJS Part 1
- Nest.js Tutorial: Build your First REST API CRUD App with TypeORM/
- NestJS TypeORM Pagination – Step By Step Guide/
- Getting started with NestJS & TypeORM (+bonus NestJS Admin)
- TypeORM With NEST JS Basic Tutorial
- Learning nestjs I
- NestJS, TypeORM and PostgreSQL — full example development and project setup working with database migrations.