26.블로그 포스트 작성 및 에디터 기능 추가, Nest.js에서 마크다운 데이터 처리

작성일: 2023년 10월 25일

작성자: 당신의 이름

소개

웹 애플리케이션을 구축할 때 블로그 포스트 작성 기능은 필수적입니다. 이 글에서는 Nest.js와 Next.js를 이용해 블로그 포스트를 작성하고 마크다운 데이터를 처리하는 방법을 알아보겠습니다. 우리는 또한 에디터 기능을 추가하여 사용자가 쉽게 콘텐츠를 작성하고 포맷할 수 있도록 할 것입니다.

Nest.js는 효과적이고 확장 가능한 서버 사이드 애플리케이션을 구축하기 위한 Node.js 프레임워크이며, Next.js는 React 기반의 서버 사이드 렌더링 프레임워크입니다. 두 프레임워크를 결합하여 풍부한 사용자 경험을 제공하는 블로그 플랫폼을 만들 수 있습니다.

기본 프로젝트 설정

이 예제에서는 Nest.js를 백엔드로, Next.js를 프론트엔드로 사용할 것입니다. 프로젝트를 시작하기 위해 다음과 같은 단계를 따르세요:

1. Nest.js 프로젝트 생성

npm i -g @nestjs/cli
nest new blog-backend
cd blog-backend

2. Next.js 프로젝트 생성

npx create-next-app blog-frontend
cd blog-frontend

이제 각 프로젝트 폴더 안에 필요한 라이브러리를 설치해야 합니다.

cd blog-backend
npm install @nestjs/typeorm typeorm sqlite3

데이터베이스 및 엔티티 설정

Nest.js에서 블로그 포스트를 관리하기 위해 TypeORM을 사용하여 데이터베이스를 설정할 것입니다. SQLite를 사용할 예정이며, `Post`라는 엔티티를 생성합니다.

1. 엔티티 생성

touch src/posts/entities/post.entity.ts

코드:

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity('posts')
export class Post {
    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    title: string;

    @Column('text')
    content: string;

    @Column()
    createdAt: Date;

    @Column()
    updatedAt: Date;
}

2. 데이터베이스 모듈 설정

물리적 데이터베이스를 사용하기 위해 TypeORM 모듈을 설정합니다.

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Post } from './entities/post.entity';
import { PostsService } from './posts.service';
import { PostsController } from './posts.controller';

@Module({
    imports: [TypeOrmModule.forFeature([Post])],
    controllers: [PostsController],
    providers: [PostsService],
})
export class PostsModule {}

CRUD 기능 구현

블로그 포스트를 CRUD(Create, Read, Update, Delete) 작업을 위한 서비스와 컨트롤러를 구현하겠습니다.

1. 서비스 구현

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Post } from './entities/post.entity';

@Injectable()
export class PostsService {
    constructor(
        @InjectRepository(Post)
        private postsRepository: Repository,
    ) {}

    create(post: Post): Promise {
        return this.postsRepository.save(post);
    }

    findAll(): Promise {
        return this.postsRepository.find();
    }

    findOne(id: number): Promise {
        return this.postsRepository.findOneBy({ id });
    }

    async update(id: number, post: Post): Promise {
        await this.postsRepository.update(id, post);
        return this.findOne(id);
    }

    async remove(id: number): Promise {
        await this.postsRepository.delete(id);
    }
}

2. 컨트롤러 구현

import { Controller, Get, Post, Body, Param, Delete, Put } from '@nestjs/common';
import { PostsService } from './posts.service';
import { Post } from './entities/post.entity';

@Controller('posts')
export class PostsController {
    constructor(private readonly postsService: PostsService) {}

    @Post()
    create(@Body() post: Post) {
        return this.postsService.create(post);
    }

    @Get()
    findAll() {
        return this.postsService.findAll();
    }

    @Get(':id')
    findOne(@Param('id') id: string) {
        return this.postsService.findOne(+id);
    }

    @Put(':id')
    update(@Param('id') id: string, @Body() post: Post) {
        return this.postsService.update(+id, post);
    }

    @Delete(':id')
    remove(@Param('id') id: string) {
        return this.postsService.remove(+id);
    }
}

마크다운 지원 설정

블로그 포스트의 내용을 마크다운 형식으로 저장하고, 이를 HTML로 변환할 수 있도록 마크다운 처리를 위한 라이브러리를 설정하겠습니다.

1. 마크다운 라이브러리 설치

npm install marked

2. 마크다운을 HTML로 변환하기

이를 위해 `PostsService`에 변환 기능을 추가합니다.

import { marked } from 'marked';

@Injectable()
export class PostsService {
    // 기존 코드 생략...

    convertMarkdownToHtml(content: string): string {
        return marked(content);
    }
}

3. HTML 변환 호출하기

게시물 생성 및 조회 시 이 함수를 호출하여 마크다운 콘텐츠를 HTML로 변환합니다.

create(post: Post): Promise {
        post.content = this.convertMarkdownToHtml(post.content);
        return this.postsRepository.save(post);
    }

Next.js에서의 에디터 기능 구현

이제 Next.js 프론트엔드를 설정하여 사용자가 블로그 포스트를 작성하고 에디팅할 수 있도록 합니다. 우리는 마크다운 에디터 라이브러리를 사용할 것이며, React를 통해 사용자 경험을 향상시킬 것입니다.

1. 마크다운 에디터 설치

npm install react-markdown

2. 포스트 작성 페이지

포스트를 작성하고 제출할 수 있는 페이지를 생성합니다.

import { useState } from 'react';
import ReactMarkdown from 'react-markdown';

const PostEditor = () => {
    const [title, setTitle] = useState('');
    const [content, setContent] = useState('');

    const handleSubmit = async (e) => {
        e.preventDefault();
        const res = await fetch('/api/posts', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ title, content }),
        });
        if (res.ok) {
            // 처리 후 필요 시 리프레시 또는 상태 갱신
        }
    };

    return (
        
setTitle(e.target.value)} placeholder="포스트 제목" required />
); }; export default PostEditor;

결론

이번 강좌에서는 Nest.js와 Next.js를 활용하여 블로그 포스트 작성 기능과 마크다운 데이터를 처리하는 방법을 알아보았습니다. Nest.js를 통해 효율적으로 데이터를 관리하고, Next.js에서는 사용자 친화적인 UI를 제공하는 방법을 배웠습니다.

이러한 기술을 활용하면 복잡한 웹 애플리케이션을 더욱 쉽게 구축하고, 사용자가 원하는 기능을 원활하게 제공할 수 있습니다. 앞으로의 개발에서도 Nest.js와 Next.js를 이용하여 당신의 아이디어를 실현해 보세요.

더 많은 내용을 원하신다면, 하단의 댓글을 통해 의견을 남겨주세요.