// server.js
const express = require("express");
const app = express();
const PORT = process.env.PORT = 3000;
let router = express.Router();
router.get('/',function(req,res){
res.json({'message' : 'Ping Successfull'});
});
app.use('/api',router);
app.listen(PORT,function(){
console.log('Server is running at PORT:',PORT);
});
Declarative approach
Feature Modules
Solid structure
Readable for Frontenders and Backenders
Node inside
Number of out-of-the-box features
@Controller('user')
@UseGuards(AuthGuard('jwt'))
@UseGuards(RoleGuard)
export class UserController {
constructor(private readonly service: UserService) {}
@Role('admin')
@Post()
async create(@Body() user: User) {
return await this.service.create(user);
}
@Role('user')
@Get(':id')
async getById(@Param() id: number) {
return await this.service.getById(id);
}
}
@Module({
import: [...],
export: [...],
controllers: [
UserController,
],
providers: [
UserService,
],
})
export class AppModule {}
async function bootstrap() {
const app = await NestFactory.create(AppModule, {
cors: true,
});
await app.listen(3100);
}
bootstrap();
ReactJS
Frontend Code
NestJS
Backend Code
Shared
Library
DTO
Validation
Modules
Controllers
Routing
Dependency Injection
Middleware
Pipes
Guards
Exceptions
Interceptors
@Injectable({
scope: Scope.DEFAULT,
})
export class UserRepository {...}
@Injectable()
export class UserService {
constructor(private readonly repository: UserRepository) {}
}
@Module({
controllers: [UserController],
providers: [UserService, UserRepository],
exports: [UserService, UserRepository],
})
export class UserModule {}
export declare enum Scope {
/**
* One for the application
*/
DEFAULT = 0,
/**
* New instance each time
*/
TRANSIENT = 1,
/**
* A new instance each request
*/
REQUEST = 2
}
@Post()
async create(
@Body() user: User,
@Req() req,
@Res() res,
) {
return await this.service.create(user);
}
@Injectable()
export class CustomMiddleware implements NestMiddleware {
use(
req: Request,
res: Response,
next: () => void) {
Logger.debug('Middleware');
next();
}
}
@Injectable()
export class AdminGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean | Promise<boolean> {
Logger.debug('Guard')
const request = context.switchToHttp().getRequest();
request.user.role === 'admin';
}
}
@UseGuards(AdminGuard)
export class Controller {}
@Injectable()
export class PerformanceInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
Logger.debug('Interceptor started')
const now = Date.now();
return next
.handle()
.pipe(
tap(() => {
Logger.debug('Interceptor completed')
Logger.log(`${this.requestTag} completed in: ${Date.now() - now}ms`)
}),
);
}
}
@Injectable()
export class LogPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
Logger.debug('Pipe');
return value;
}
}
@UsePipes(new LogPipe())
export class Controller {}
Middleware
Pipes
Guards
Controller
Interceptor Start
Interceptor End
Exception Filter
@Injectable()
export class EveryMinuteService {
@Cron(CronExpression.EVERY_5_SECONDS)
handleEveryMinuteJob() {
Logger.debug(`I was called at: ${new Date()}`);
}
}
import { ApiProperty } from '@nestjs/swagger';
export class Email {
@ApiProperty()
email: string;
}
@ApiTags('auth')
@Controller('auth')
export class AuthController {...}
async function bootstrap() {
const app = await NestFactory.create(AppModule, {
cors: true,
});
SwaggerModule.setup('swagger', app,
SwaggerModule.createDocument(app, { ... }));
await app.listen(config.api.port);
}
bootstrap();
export class UserDto {
@IsPositive()
id: number;
@IsString()
name: string;
@IsEmail()
email: string;
@IsDate()
birthday: Date;
}
@UsePipes(new ValidationPipe({ transform: true }))
@Controller('users')
export class UserController {...}
Microservices
JWT Auth
Life Cycle Events
Web Sockets
GraphQL
CQRS
Template Rendering
Performance - Fastify
npm install --save hbs
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.setBaseViewsDir(join(__dirname, '..', 'views'));
app.setViewEngine('hbs');
await app.listen(3000);
}
bootstrap();
<html>
<body>
{{ message }}
</body>
</html>
@Controller()
export class AppController {
@Get()
@Render('index')
root() {
return { message: 'Test Handlebar templates' };
}
}
npm i --save @nestjs/platform-fastify
async function bootstrap() {
const app = await NestFactory
.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter()
);
await app.listen(3000);
}
bootstrap();
github.com/valentinkononov/nester