---
# System prepended metadata

title: NestJS
tags: [nestjs]

---

# 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();
```