# NestJS
###### tags: `nestjs`
## For detail
https://github.com/giahuy405/movie-capstone
## Set up file
install nest CLI
```javascript
npm i -g @nestjs/cli
nest -v // check version
nest --version // if the command above is not working try this
```
**Create new project**
```javascript
nest new name_project
node -v // version of node must be larger than 14.
```
**run project**
```
yarn start -> node
yarn start:dev -> nodemon
```
**heirachy in nestjs**
```javascript
@Controller('app') //CONTROLER
export class AppController {
constructor(private readonly appService: AppService) {}
@Get('hello')
getHello(): string {
return this.appService.getHello();
}
}
```
```javascript=
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World 2!';
}
}
```
## query request
```javascript=
query string: localhost:4000?id=1&hoTen=abc
query params: localhost:4000/1/abc (/:id/:hoTen)
// the first way, but it don't support for generating swagger
@Get('hello/:id/:name')
getHello(@Req() req:Request): string {
const {id} = req.params;
const {email,password} = req.body;
return this.appService.getHello();
}
// the second way
interface bodyApp {
email: string;
password: string;
}
@HttpCode(200)
@Get('hello/:id2/:name2')
getHello(
// use decorator of nestjs, it will support when create swagger
@Req() req: Request,
@Query('id') id: string,
@Query('name') name: string,
@Param('id2') id2: string,
@Query('name2') name2: string,
@Body() body: bodyApp,
@Headers('token') headers,
): string {
let { email, password } = body;
return this.appService.getHello();
}
domain : localhost:8080/app/hello/1/abc?id=2&name=xyz
id=2&name=xyz query string
1/abc query params
```
create module
```javascript
nest g module <name object here>
nest g controller <name object here> --no-spec
nest g service <name object here> --no-spec
```
fast create Dto,interface,CRUD
```javascript
nest g resource <name object here> --no-spec
```
## cors
```javascript!
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// enable CORS
app.enableCors();
app.use(express.static('.'));
await app.listen(3000);
}
bootstrap();
```
## env variable
```javascript
yarn add @nestjs/config
```
file `app.module.ts`
```javascript!
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [UsersModule, FoodModule, ConfigModule.forRoot({ isGlobal: true })],
controllers: [AppController],
providers: [AppService],
```
using in `users.controller.ts`,remember to use `localhost:5000/users/get-env` if we use postman, we cann't see the `variable`
```javascript!
import { Controller, Get } from '@nestjs/common';
import { ConfigService } from '@nestjs/config'; // add
@Controller('users')
export class UsersController {
constructor(
private userService: UsersService,
private configService: ConfigService,
) {}
@Get('get-env')
getEnv(): string {
let data: string = this.configService.get('TITLE'); // add
return data;
}
}
```
note: restart nodemon to take new env variable.
## throw error
```javascript!
login(){
throw new HttpException('Email ko đúng',404);
throw new HttpException('Email ko đúng',HttpStatus.AMBIGUOUS);
throw new NotFoundException('Email ko đúng')
}
```
## JWT
```javascript
yarn add @nestjs/passport passport passport-local @nestjs/jwt passport-jwt @types/passport-jwt
```
```javascript=
import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(config: ConfigService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: config.get('SECRET_KEY'),
});
}
async validate(payload: any) {
return payload;
}
}
```
## upload
```javascript
yarn add -D @types/multer
```
```javascript=
@UseInterceptors(FileInterceptor('file',{
storage:diskStorage({
destination:'./images',
filename:(req,file,cb)=>{
console.log(file)
cb(null,Date.now() + "_" + file.originalname);
}
})
}))
```
or
```javascript=
@UseInterceptors(
FileInterceptor('image', {
storage: diskStorage({
destination: process.cwd() + '/public/images',
filename: (req, file, cb) => {
console.log(file);
cb(null, Date.now() + '_' + file.originalname);
},
}),
}),
)
@Post('upload-film/:filmId')
uploadAvatar(@UploadedFile()
file: Express.Multer.File,
@Param("filmId") filmId:string)
{
return this.filmService.uploadAvatar(filmId,file);
}
```
and this file `film.services.ts`
```javascript=
// also upload and update
async uploadAvatar(filmId: string, file: Express.Multer.File) {
try {
const film = await this.prisma.film.findFirst({
where: {
film_id: Number(filmId),
},
});
// thay path
film.image = file.filename;
// lưu vào db
await this.prisma.film.update({
data: film,
where: {
film_id: Number(filmId),
},
});
return { message: 'Upload Successfully' };
} catch (err) {
throw new HttpException('Failed', 400);
}
}
```
## swagger
```javascript
yarn add @nestjs/swagger swagger-ui-express
```
file `main.ts`
```javascript=
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as express from 'express';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors();
app.use(express.static('.'))
const config = new DocumentBuilder()
.setTitle('swager nè')
.setVersion('1.1')
.setDescription('Swagger movie')
.addBearerAuth() // bearer authenticate
.build();
const document = SwaggerModule.createDocument(app,config);
SwaggerModule.setup('/tengicungduoc',app,document);
// localhost:5431/tengicungduoc -> access to swagger
await app.listen(5431);
}
bootstrap();
```
file `user.controller.ts`, this is used for titled api, put it on
```javascript=
@ApiTags('user')
```
put it on the other decorator
```javascript=
@ApiTags('Film manager') // set the title for the api
@Controller('film-manager')
export class FilmController {
constructor(private readonly filmService: FilmService) {}
@Get('banner-list')
bannerList() {
return this.filmService.bannerList();
}
```
for API with bearer auth
```javascript=
@ApiBearerAuth() // add this
@UseGuards(AuthGuard('jwt'))
@Get('get-user-type')
getUserType() {
return this.userService.getUserType();
}
```
and dont forget to
```javascript=
const config = new DocumentBuilder()
.setTitle('Swagger movie API')
.addBearerAuth() // add this line
.build();
```