반응형
Express 에서 개발을 했을 때 로직 구현을 Controller 에서 모두 구현을 했었다.
NestJS 에서는 Java Spring 처럼 Service에서 로직 구현 후 컨트롤러에서 불러오는 코드를 작성한다고 한다.
Controller 에 작성된 코드를 Service로 옮겨보자
posts.controller.ts / Service 로 수정 전
import { Body, Controller, Delete, Get, NotFoundException, Param, Post, Put } from '@nestjs/common';
import { PostsService } from './posts.service';
interface PostModel {
id: number;
author: string;
title: string;
content: string;
likeCount: number;
commentCount: number;
}
let posts: PostModel[] = [
{
id: 1,
author: 'author_test',
title: 'title_test',
content: 'title_test',
likeCount: 0,
commentCount: 0,
},
{
id: 2,
author: 'author_test2',
title: 'title_test2',
content: 'title_test2',
likeCount: 1,
commentCount: 1,
},
{
id: 3,
author: 'author_test3',
title: 'title_test3',
content: 'title_test3',
likeCount: 3,
commentCount: 3,
},
];
@Controller('posts')
export class PostsController {
constructor(private readonly postsService: PostsService) {}
// 1) GET /posts 모든 게시물을 가져온다
@Get()
getPosts() {
return posts;
}
// 2) GET /posts/:id
// id에 해당하는 게시물을 가져온다
@Get(':id')
getPost(@Param('id') id: string) {
const post = posts.find((post) => post.id === +id);
if (!post) {
throw new NotFoundException();
} else {
return post;
}
}
// 3) POST /posts 게시물을 변경한다
@Post('')
postPost(@Body('author') author: string, @Body('title') title: string, @Body('content') content: string) {
const post = {
id: posts[posts.length - 1].id + 1,
author,
title,
content,
likeCount: 0,
commentCount: 0,
};
posts = [...posts, post];
return post;
}
// 4) PUT /posts/:id id에 해당하는 개시물을 변경한다
@Put(':id')
putPost(
@Param('id') id: string,
@Body('author') author?: string,
@Body('title') title?: string,
@Body('content') content?: string,
) {
const post = posts.find((post) => post.id === +id);
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 === +id ? post : prevPost));
return post;
}
// 5) DELETE /posts/:id id에 해당하는 개시물을 삭제
@Delete(':id')
deletePost(@Param('id') id: string) {
const post = posts.find((post) => post.id === +id);
if (!post) {
throw new NotFoundException();
}
posts = posts.filter((post) => post.id !== +id);
return id;
}
}
posts.controller.ts / Service 로 수정 후
import { Body, Controller, Delete, Get, NotFoundException, Param, Post, Put } from '@nestjs/common';
import { PostsService } from './posts.service';
@Controller('posts')
export class PostsController {
constructor(private readonly postsService: PostsService) {}
// 1) GET /posts 모든 게시물을 가져온다
@Get()
getPosts() {
return this.postsService.getAllPosts();
}
// 2) GET /posts/:id
// id에 해당하는 게시물을 가져온다
@Get(':id')
getPost(@Param('id') id: string) {
return this.postsService.getPostById(+id);
}
// 3) POST /posts 게시물을 변경한다
@Post('')
postPost(@Body('author') author: string, @Body('title') title: string, @Body('content') content: string) {
return this.postsService.createPost(author, title, content);
}
// 4) PUT /posts/:id id에 해당하는 개시물을 변경한다
@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에 해당하는 개시물을 삭제
@Delete(':id')
deletePost(@Param('id') id: string) {
return this.postsService.deletePost(+id);
}
}
posts.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
export interface PostModel {
id: number;
author: string;
title: string;
content: string;
likeCount: number;
commentCount: number;
}
let posts: PostModel[] = [
{
id: 1,
author: 'author_test',
title: 'title_test',
content: 'title_test',
likeCount: 0,
commentCount: 0,
},
{
id: 2,
author: 'author_test2',
title: 'title_test2',
content: 'title_test2',
likeCount: 1,
commentCount: 1,
},
{
id: 3,
author: 'author_test3',
title: 'title_test3',
content: 'title_test3',
likeCount: 3,
commentCount: 3,
},
];
@Injectable()
export class PostsService {
getAllPosts() {
return posts;
}
getPostById(id: number) {
const post = posts.find((post) => post.id === +id);
if (!post) {
throw new NotFoundException();
} else {
return post;
}
}
createPost(author: string, title: string, content: string) {
const post = {
id: posts[posts.length - 1].id + 1,
author,
title,
content,
likeCount: 0,
commentCount: 0,
};
posts = [...posts, post];
return post;
}
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) {
const post = posts.find((post) => post.id === postId);
if (!post) {
throw new NotFoundException();
}
posts = posts.filter((post) => post.id !== postId);
return postId;
}
}
한 눈에 봐도 컨트롤러의 코드가 깔끔해졌다.
Service 에 작성된 함수들을 보면 이전 컨트롤러에서완 다르게 함수 위에 데코레이터가 없는 모습을 볼 수 있다.
한 마디로 Http Method, Path에 상관 없이 Service를 import 해온다면
두 개의 클래스가 디커플링되어 로직에 맞게 어디서든 함수를 사용 할 수 있다는 것
코드의 재사용성이 좋아진다는 점이다.
반응형
'nestJS' 카테고리의 다른 글
NestJS | Config (env) (0) | 2024.08.25 |
---|---|
NestJS | Pagination 페이지네이션 (0) | 2024.08.22 |
NestJS | Session vs JWT Token , Refresh Token & Access Token (0) | 2024.08.18 |
NestJS | Controller | 모듈 생성하기, Postman 요청 보내기 (0) | 2024.08.13 |
NestJS 시작하기 (1) | 2023.12.15 |