728x90
프로바이더로 NestJS에서 전형적으로 사용하는 Service에 대해 알아보도록 함
처음 NestJS폴더를 생성했을때, controller가 있거, module이 있고 service가 있다
이 3종류는 셋트같은 개념이다.
controller에서 구현을 다 했는데, 왜 service가 필요한것인가? controller와 service의 차이는?
controller같은 경우에 아키텍처라는 개념이 생김 아키텍처란? 좋은방법으로 코드를 쓰면, 실패하거나 협업이 어려운 일을 최소할 수 있다.
controller파일이 담당하는것은 말 그대로 가장 맨 앞에서 요청을 받는 역할을 함 = 최전방에서 요청이 어디로 가야 될지를 함수로 라우팅 해주는 역할을 함 = 컨트롤러는 오직 그 역할만 하고 그 역할에 포커스가 되어있어야함
NestJS에서 정의하는 controller는 로직을 컨트롤러 단위안에서 정의하지 말라고 써둠 긴 로직은 service파일에 정의하라고 함 service에 정의하고 controller에서는 service파일을 불러와서 사용하라고 이야기함
constructor(private readonly postsService: PostsService) {}
controller가 생성되면 당연히 service가 같이 생성이 되어야하고, controller에서는 로직을 작성하지않고 service파일에 정의 한 후 불러와 사용
- 재활용성이 높아짐
서비스 파일은 컨트롤러에서 했던것처럼 특정 라우트에 대한 태그들이 없다(annotation안씀)
앞서 한꺼번에 작성했던거를 두 파일에 나눠 작성한 결과
// posts.controller.ts
/* eslint-disable prettier/prettier */
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Put,
} from '@nestjs/common';
import { PostsService } from './posts.service';
@Controller('posts')
export class PostsController {
constructor(private readonly postsService: PostsService) {}
// 1) GET /posts
// 모든 post를 다 가져온다
@Get()
getPosts() {
return this.postsService.getAllPosts();
}
// 2) GET /posts/:id
// id에 해당되는 post를 가져온다 => path parameter를 만들어야 함!!
// 예를들어서 id=1일 경우 id가 1인 포스트를 가져온다
@Get(':id')
// :은 Param 이라는 뜻이라 id만 정의해주면 됨
getPost(@Param('id') id: string) {
return this.postsService.getPostById(+id);
}
// 3) POST /posts
// POST를 생성한다
@Post()
postPost(
@Body('author') author: string, // 데이터를 body에서 받을건데, body안에 author라는 키 안에 있는 값을 author라는 string파라미터에 저장한다.
@Body('title') title: string,
@Body('content') content: string,
) {
return this.postsService.createPost(author, title, content);
}
// 4) PUT /posts
// id에 해당되는 POST를 변경한다
@Put(':id')
putPost(
@Param('id') id: string,
// 변경하고 싶은 요소만 따로 받아서 요청을 보내면 되는데, 어떤요소를 변경하고싶은지 모름
// 그래서 물음표를 붙여줘야함
@Body('author') author?: string,
@Body('title') title?: string,
@Body('content') content?: string,
) {
return this.postsService.updatePost(+id, author, title, content);
}
// 5) DELETE /posts/:id
// id에 해당되는 post를 삭제한다
@Delete(':id')
deletePost(@Param('id') id: string) {
return this.postsService.deletePost(+id);
}
}
//posts.service.ts
/* eslint-disable prettier/prettier */
import { Injectable, NotFoundException } from '@nestjs/common';
/**
* id : number
* authour : string
* title : string
* content : string
* likeCount : number
* commentCount : number
*/
export interface PostModel {
id: number;
author: string;
title: string;
content: string;
likeCount: number;
commentCount: number;
}
// let으로 설정한 이유 : 데이터를 추가,삭제,변경 할것이기 때문
let posts: PostModel[] = [
{
id: 1,
author: 'newjeans_official',
title: '뉴진스 민지',
content: '메이크업 고치고 있는 민지',
likeCount: 1000000,
commentCount: 99999,
},
{
id: 2,
author: 'newjeans_official',
title: '뉴진스 해린',
content: '노래연습하고있는 해린',
likeCount: 1000000,
commentCount: 99999,
},
{
id: 3,
author: 'blackpink_official',
title: '블랙핑크 로제',
content: '종합운동장에서 공연중인 로제',
likeCount: 1000000,
commentCount: 99999,
},
];
@Injectable()
export class PostsService {
getAllPosts() {
return posts;
}
getPostById(id: number) {
const post = posts.find((post) => {
post.id === +id;
});
// post가 없을때, Not Found Exception 던지기 (404 Not Found 에러)
// 에러 반환하는 이유 : 아무것도 없는 값을 반환해주는것이아닌 문제가 있다는 실질적인 메세지를 전달하기 위함
if (!post) {
throw new NotFoundException();
}
return post; // (200 OK)
}
createPost(author: string, title: string, content: string) {
// 생성할 포스트 데이터에 맞게 post 만듦
const post: PostModel = {
id: posts[posts.length - 1].id + 1,
author,
title,
content,
likeCount: 0,
commentCount: 0,
};
// posts는 기존의 posts와 새로 만든 post를 넣는다.
posts = [...posts, post];
// 응답은 새로 만든 post만 반환한다.
// 허용되는 정보 안에서 최소한의 데이터를 반환해주는것이 가장 좋다.
// 최소한의 정보를 주되, 꼭 필요한 정보는 모두 담아서 반환을 해줘야함.
// 이유 : 서버를 클라우드에 올리면 데이터를 얼마나 보냈냐에 따라서 과금을 함.
return post; // (201 Created)
}
updatePost(
postId: number,
author?: string,
title?: string,
content?: string,
) {
const post = posts.find((post) => post.id === postId);
if (!post) {
throw new NotFoundException();
}
if (author) {
post.author = author;
}
if (title) {
post.title = title;
}
if (content) {
post.content = content;
}
posts = posts.map((prevPost) =>
prevPost.id === +postId ? post : prevPost,
);
return post;
}
deletePost(postId: number) {
// id가 없다면 NotFoundException를 던지는 로직
const post = posts.find((post) => post.id === postId);
if (!post) {
throw new NotFoundException();
}
// id가 있으면 posts에 필터해서 삭제함
posts = posts.filter((post) => post.id !== postId);
// 삭제한 포스트의 id를 반환함
return postId;
}
}
'3. Backend > NestJS' 카테고리의 다른 글
[코드팩토리 NestJS 강의] AppModule과 main.ts 파일 (0) | 2024.03.13 |
---|---|
[코드팩토리 NestJS 강의] Module, Provider and Inversion of Control (제어의 역전) (2) | 2024.03.12 |
[코드팩토리 NestJS 강의] Query and Parameters (쿼리와 파라미터) (0) | 2024.03.12 |
[코드팩토리 NestJS 강의] Controller (컨트롤러) (0) | 2024.03.12 |
[코드팩토리 NestJS 강의] nodeJS와 Express를 사용해서 기본적인 서버 만들기 (3) | 2024.03.08 |