Andrey Kucherenko
Creator and curator of training platform for developers - https://startupemulator.com/. Math.random() community leader - https://t.me/mathrandomcommunity Engineer with more than 21 years of experience in IT.
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
import { Controller, Get } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Get()
findAll() {
return 'This action returns all cats';
}
}
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
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();
}
}
@Post()
async create(@Body() createCatDto: CreateCatDto) {
throw new HttpException({
status: HttpStatus.FORBIDDEN,
error: 'This is a custom message',
}, 403);
}
@Post()
@UsePipes(new JoiValidationPipe(createCatSchema))
async create(@Body() createCatDto: CreateCatDto) {
this.catsService.create(createCatDto);
}
import {
PipeTransform, Injectable, ArgumentMetadata
} from '@nestjs/common';
@Injectable()
export class ValidationPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
return value;
}
}
@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {}
import {
Injectable, CanActivate, ExecutionContext
} from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
return validateRequest(request);
}
}
@UseInterceptors(LoggingInterceptor)
export class CatsController {}
import {
Injectable, NestInterceptor, ExecutionContext
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
intercept(
context: ExecutionContext,
call$: Observable<any>,
): Observable<any> {
console.log('Before...');
const now = Date.now();
return call$.pipe(
tap(() => console.log(`After... ${Date.now() - now}ms`)),
);
}
}
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
describe('CatsController', () => {
let catsController: CatsController;
let catsService: CatsService;
beforeEach(() => {
catsService = new CatsService();
catsController = new CatsController(catsService);
});
describe('findAll', () => {
it('should return an array of cats', async () => {
const result = ['test'];
jest.spyOn(catsService, 'findAll').mockImplementation(() => result);
expect(await catsController.findAll()).toBe(result);
});
});
});
import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
describe('CatsController', () => {
let catsController: CatsController;
let catsService: CatsService;
beforeEach(async () => {
const module = await Test.createTestingModule({
controllers: [CatsController],
providers: [CatsService],
}).compile();
catsService = module.get<CatsService>(CatsService);
catsController = module.get<CatsController>(CatsController);
});
describe('findAll', () => {
it('should return an array of cats', async () => {
const result = ['test'];
jest.spyOn(catsService, 'findAll').mockImplementation(() => result);
expect(await catsController.findAll()).toBe(result);
});
});
});
import { Test, TestingModule } from '@nestjs/testing';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
describe('AppController (e2e)', () => {
let app;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('/ (GET)', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
});
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('Cats example')
.setDescription('The cats API description')
.setVersion('1.0')
.addTag('cats')
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup('api', app, document);
await app.listen(3001);
}
bootstrap();
@Post()
async create(@Body() createCatDto: CreateCatDto) {
this.catsService.create(createCatDto);
}
class CreateCatDto {
@ApiModelProperty()
readonly name: string;
@ApiModelProperty()
readonly age: number;
@ApiModelProperty()
readonly breed: string;
}
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'root',
database: 'test',
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true,
}),
],
})
export class ApplicationModule {}
import {
Entity, Column, PrimaryGeneratedColumn
} from 'typeorm';
@Entity()
export class Photo {
@PrimaryGeneratedColumn()
id: number;
@Column({ length: 500 })
name: string;
@Column('text')
description: string;
@Column()
filename: string;
@Column('int')
views: number;
@Column()
isPublished: boolean;
}
import { Injectable, Inject } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Photo } from './photo.entity';
@Injectable()
export class PhotoService {
constructor(
@InjectRepository(Photo)
private readonly photoRepository: Repository<Photo>,
) {}
async findAll(): Promise<Photo[]> {
return await this.photoRepository.find();
}
}
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
@Module({
imports: [MongooseModule.forRoot('mongodb://localhost/nest')],
})
export class ApplicationModule {}
import * as mongoose from 'mongoose';
export const CatSchema = new mongoose.Schema({
name: String,
age: Number,
breed: String,
});
import { Model } from 'mongoose';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';
@Injectable()
export class CatsService {
constructor(@InjectModel('Cat') private readonly catModel: Model<Cat>) {}
async create(createCatDto: CreateCatDto): Promise<Cat> {
const createdCat = new this.catModel(createCatDto);
return await createdCat.save();
}
async findAll(): Promise<Cat[]> {
return await this.catModel.find().exec();
}
}
$ npm i --save helmet
$ npm i --save csurf
$ npm i --save express-rate-limit
import * as csurf from 'csurf';
import * as helmet from 'helmet';
import * as rateLimit from 'express-rate-limit';
// somewhere in your initialization file
app.use(helmet());
app.use(csurf());
app.use(rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
}));
By Andrey Kucherenko
Creator and curator of training platform for developers - https://startupemulator.com/. Math.random() community leader - https://t.me/mathrandomcommunity Engineer with more than 21 years of experience in IT.