Slide 1

Slide 1 text

October 9, 2019 | Node.js Paris | Sylvain Pontoreau NestJS introduction NestJS

Slide 2

Slide 2 text

Writer In ❤ with Co-organizer Who I am? @spontoreau Formerly Microsoft

Slide 3

Slide 3 text

Paris TypeScript @ParisTypeScript www.typescript.paris

Slide 4

Slide 4 text

What is NestJS? • A Node.js MVC framework • Progressive • Written in TypeScript • Project organization inspired by Angular • A lot of modules: • Endpoint: Rest, GraphQL, WebSocket, ... • Data: TypeORM, Mongoose, ... • Communication: MQTT, RabbitMQ, gRPC, … • Others: Elastic Search, OpenAPI, Health checks, JWT, CQRS ... • Amazing documentation: https://docs.nestjs.com • Huge community (20k stars on Github, 120 contributors on the core) • CLI

Slide 5

Slide 5 text

Create a project • Install CLI: • Create a project: $ npm install –g @nestjs/cli $ nest new appName

Slide 6

Slide 6 text

Controllers import { Controller, Get } from '@nestjs/common'; @Controller() export class UserController { @Get('hello') get(): string { return 'Hello world!'; } } • Verbs: • @Get • @Post • @Put • @Delete • @Patch • ... • Actions & decorators: • @Param(key?: string) -> req.params • @Body(key?: string) -> req.body • @Headers(key?: string)-> req.headers • @Request(), @Response(), @Next() • ...

Slide 7

Slide 7 text

Services / Providers • A dependency to inject • Close to the Angular concept • Have to be injected • @Injectable • Example: import { Injectable } from '@nestjs/common'; @Injectable() export class UserService { findAll(): User[] { return [ // ... ]; } } import { Controller, Get } from '@nestjs/common'; import { UserService } from 'user.service'; @Controller() export class UserController { constructor( private readonly userService: UserService ) { } @Get() getAll(): User[] { this.userService.findAll(); } } user.service.ts user.controller.ts

Slide 8

Slide 8 text

Modules • Organize the application structure • A class annotated with @Module() • Contains: • providers, controllers, imports, exports • Example: import { Module } from '@nestjs/common'; import { UserService } from './user.service'; import { UserController } from './user.controller'; @Module({ imports: [], controllers: [UserController], providers: [ UserService, ], }) export class UserModule {}

Slide 9

Slide 9 text

Other capabilities • Middleware import { Injectable, NestMiddleware } from '@nestjs/common'; import { Request, Response } from 'express'; @Injectable() export class LoggerMiddleware implements NestMiddleware { use(req: Request, res: Response, next: Function) { console.log('Request...'); next(); } } import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common'; import { LoggerMiddleware } from './common/middleware/logger.middleware'; import { UserModule } from './user/user.module'; import { UserController } from './user.controller'; @Module({ imports: [UserModule], }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer.apply(LoggerMiddleware) .forRoutes(UserController); } } logger.middleware.ts app.module.ts

Slide 10

Slide 10 text

Other capabilities • Validation with class-validator import { IsString, IsEmail, IsNotEmpty } from 'class-validator'; export class PostUserModel { @IsNotEmpty() @IsString() firstName: string; @IsNotEmpty() @IsString() lastName: string; @IsNotEmpty() @IsEmail() email: string; } import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { ValidationPipe } from '@nestjs/common'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.useGlobalPipes(new ValidationPipe()) await app.listen(3000); } bootstrap(); postUser.model.ts main.ts

Slide 11

Slide 11 text

Data access • Example with TypeORM: import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm'; @Entity() export class User { @PrimaryGeneratedColumn() id: number; @Column() firstName: string; @Column() lastName: string; @Column() email: string; } import { createConnection } from 'typeorm'; export const databaseProviders = [ { provide: 'DatabaseConnection', useFactory: async () => await createConnection({ type: 'mysql', // ... }) }, ]; user.entity.ts database.provider.ts

Slide 12

Slide 12 text

Data access • Example with TypeORM: import { Injectable, Inject } from '@nestjs/common'; import { Repository, Connection } from 'typeorm'; import { User } from './user.entity'; @Injectable() export class UserService { private readonly userRepository: Repository constructor( @Inject('DatabaseConnection') connection: Connection ) { this.userRepository = connection.getRepository(User); } async findAll(): Promise { return await this.userRepository.find(); } } user.service.ts

Slide 13

Slide 13 text

Open API • Installation: import { NestFactory } from '@nestjs/core'; import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; import { ApplicationModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(ApplicationModule); const options = new DocumentBuilder() .setTitle('User API') .setDescription('The user API description') .setVersion('1.0') .addTag('user') .build(); const document = SwaggerModule.createDocument(app, options); SwaggerModule.setup('api', app, document); await app.listen(3000); } bootstrap(); $ npm install --save @nestjs/swagger swagger-ui-express • Decorators: • @ApiModelProperty • @ApiModelPropertyOptional • @ApiImplicitQuery • @ApiUseTags • @ApiResponse • @ApiBearerAuth • ...

Slide 14

Slide 14 text

Demo

Slide 15

Slide 15 text

Resources • NestJS website: https://nestjs.com • NestJS & Fastify: https://docs.nestjs.com/techniques/performance • Demo (Github repository): https://github.com/spontoreau/nestjs-nodejs-paris

Slide 16

Slide 16 text

Questions?

Slide 17

Slide 17 text

Thank you!