런타임
: 언어가 실행될 수 있는 환경.(JS는 브라우저에서만 사용이 가능하기 때문에 NodeJS같은 런타임을 이용해 브라우저 외에도 사용가능하게 만들어준다.)프레임워크
: 완성된 제품이 아닌 완성된 제품을 만들기 위해서 개발자를 도와주는 역할 (스프링, 장고, 노드 등)라이브러리
: 특정 기능에 대한 도구 또는 함수들의 집합 (jquery 등)차이점
: 둘의 차이점은 라이브러리는 내가 필요한 경우 가져다 쓰고 프레임 워크는 정해진 규칙이 있어 우리가 따라야함- 프레임 워크는 집! 라이브러리는 가구!
- 리액트가 애매하게 내가 필요한 경우 불러올 수 있어서 라이브러리기도한데 동시에 컴포넌트를 불러와서 프레임워크라고도 불림
그럼 왜 Node.js는 백엔드 영역이라는 오해가 생겼을까?
Node.js를 통해서 서버도 만들 수 있기 때문이다.
https://backback.tistory.com/383 - nestjs 자세한 설명
@Get('/hello')
sayHello(): string {
return 'Hello everyone';
}
main.ts 파일에서 AppModule을 불러와 실행시키는데 AppModule은 전체 파일을 대표하여 실행된다.
this는 클래스 내부에 있는 함수를 가져와 사용하게 해준다.
따라서 아래 코드와 함께 보면 constructor로 AppService 클래스를 불러오고 그것을 아래 getHello함수에서 appService.getHello 함수를 불러 올 수 있게 해준다.
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(); // AppService 클래스의 getHello 함수를 불러온다.
}
$ nest
$ nest g co // nest 입력 후 나오는 표에서 controller에 맞는 단축어는 'co'이므로
// g 뒤에 입력, g는 nest에서 보여주는 표에 적힌 문법임
// controller 파일 생성
//hostman - localhost:3000/movies/1
@Get('/:id')
getOne(){
return 'This will return one movie';
}
@Get() //전체를 가져옴
getAll() {
return '';
}
@Get('/:id') //하나만 가져옴
getOne(@Param('id') id(변수명): string(타입)) {
return `${id}`; //템플릿 리터럴 ${}은 작은따옴표(')나 큰따옴표(") 대신 백틱(`)(grave accent)로 감싼다.
}
@Post()
create(){
return 'This will create a movie';
}
@Delete('/:id')
remove(@Param('id') movieId: string) {
return `This will delete a movie with the id: ${movieId}`;
}
// @Put() //전체 수정
@Patch('/:id') //부분 수정
patch(@Param('id') movieId: string) {
return `This will patch a movie with the id: ${movieId}`;
}
//body(JSON)
{
"name": "Tenet",
"director": "Nolan"
}
@Post()
create(@Body() movieData) { //@Body 데코레이터는 movieData안의 리퀘스트 바디를 가져오기 위함
return movieData;
}
@Patch('/:id') //부분 수정
patch(@Param('id') movieId: string, @Body() updateData) { //필요한 파라미터를 요청해야함
return {
updateMovie:movieId,
...updateData,
};
}
@Get("search")
search(@Query("year") searchingYear:string){
return `We are searching for a movie made after: ${searchingYear}`
}
//movies.service.ts
getOne(id: string): Movie {
const movie = this.movies.find(movie => movie.id === +id); //+붙임
if(!movie) {
throw new NotFoundException(`Movie with ID ${id} not found.`);
}
return movie;
}
// ./users/dto/update-movie-dto.ts
import { IsNumber, IsString } from 'class-validator';
export class UpdateMovieDto{
@IsString()
readonly title?: string;
@IsNumber()
readonly year?: number;
@IsString({ each: true })
readonly genres?: string[];
}
// create-movie-dto.ts 파일내용 그대로 복붙 (? == 읽기전용, 부분만 수정이 가능하도록 필수가 아니게 설정)
// update-movie에서 ?를 사용하려니 service에서 맞지않는 type이라는 에러가 발생함. 아래에 다른 명령어 있느니 참고
// movies.controller.ts
@Patch('/:id') //부분 수정
patch(@Param('id') movieId: number, @Body() updateData: UpdateMovieDto) { //UpdateMovieDto 추가
return this.moviesService.update(movieId, updateData);
}
// movies.service.ts
update(id: number, updateData: UpdateMovieDto) { //UpdateMovieDto 추가
const movie = this.getOne(id);
this.deleteOne(id);
this.movies.push({ ...movie, ...updateData });
}
$ npm i @nestjs/mapped-types
import { PartialType } from '@nestjs/mapped-types';
import { IsNumber, IsString } from 'class-validator';
import { CreateMovieDto } from './create-movie.dto';
export class UpdateMovieDto extends PartialType(CreateMovieDto) {
}
//create-movie-dto.ts
import { IsNumber, IsOptional, IsString } from 'class-validator';
export class CreateMovieDto{
@IsString()
readonly title: string;
@IsNumber()
readonly year: number;
@IsOptional() //optional 추가
@IsString({ each: true })
readonly genres: string[];
}
//터미널에 입력
$ nest
$ nest g module
//변경전
//app.modules.ts
@Module({
imports: [],
controllers: [MoviesController],
providers: [MoviesService],
})
export class AppModule {}
//변경후
//app.modules.ts
import { Module } from '@nestjs/common';
import { MoviesModule } from './movies/movies.module';
@Module({
imports: [MoviesModule],
controllers: [],
providers: [],
})
export class AppModule {}
//movies.modules.ts
import { Module } from '@nestjs/common';
import { MoviesController } from './movies.controller';
import { MoviesService } from './movies.service';
@Module({
controllers: [MoviesController],
providers: [MoviesService],
})
export class MoviesModule {}
//폴더 경로
src
src/app.module.ts
src/app.controller.ts
src/app.service.ts
src/main.ts
>src
├─ >movies
│ ├─ >dto
│ │ ├─ create-movie.dto.ts
│ │ └─ update-movie.dto.ts
│ │
│ ├─ >entities
│ │ └─ movie.entity.ts
│ │
│ ├─ movies.controller.ts
│ ├─ movies.module.ts
│ └─ movies.service.ts
//파일이 없는경우 아래 명령어로 생성하기
$ nest
$ nest g s
$ nest g co
@Get()
getAll(@Req() Req, @Res() Res): Movie[] { //@Req, Res를 적어주므로 Express에 접근이 가능
return this.moviesService.getAll();
}
//그런데 NestJS는 두 개의 프레임워크를 작동하기때문에 req나 res같은 Express 객체를 직접적으로 사용하는게 좋은 방법은 아님