15.Next.js와 Nest.js 연동하여 데이터 가져오기, 블로그 목록 페이지와 상세 페이지에 데이터 연결하기

이번 글에서는 Next.jsNest.js를 활용하여 블로그 목록 페이지와 상세 페이지에 데이터를 연동하는 방법에 대해 자세히 알아보겠습니다. Next.js는 React 기반의 프레임워크로, 서버 사이드 렌더링과 정적 사이트 생성을 지원하여 최적의 성능을 자랑합니다. Nest.js는 Node.js 애플리케이션을 위한 강력한 프레임워크로, 특히 RESTful API 개발에 적합합니다. 이 두 프레임워크를 결합하여 효율적인 웹 애플리케이션을 만들 수 있습니다.

1. 프로젝트 구조 설정

먼저, 두 프레임워크를 연동할 프로젝트 구조를 설정합니다. Nest.js를 백엔드 API 서버로, Next.js를 프론트엔드 웹 애플리케이션으로 사용할 것입니다.

  • 프로젝트 루트 폴더
    • nest-backend/
    • next-frontend/

1.1 Nest.js 프로젝트 생성

먼저, Nest.js 프로젝트를 생성합니다. Nest CLI를 사용하여 새로운 프로젝트를 생성하고 의존성을 설치합니다.

            
            npm install -g @nestjs/cli
            nest new nest-backend
            cd nest-backend
            npm install @nestjs/typeorm typeorm mysql2
            
            

여기서는 MySQL을 데이터베이스로 사용하였지만, 필요한 경우 다른 데이터베이스를 사용할 수도 있습니다.

1.2 Next.js 프로젝트 생성

그 다음, Next.js 프로젝트를 생성합니다. create-next-app을 사용하여 빠르게 설정할 수 있습니다.

            
            npx create-next-app next-frontend
            cd next-frontend
            npm install axios
            
            

axios는 클라이언트에서 API를 호출할 때 사용할 라이브러리입니다.

2. Nest.js API 구축

Nest.js를 사용하여 블로그 API를 구축합니다. 블로그 포스트를 다루기 위해 Post 엔티티를 생성하고, CRUD 기능을 구현합니다.

2.1 Post 엔티티 생성

Nest.js의 TypeORM을 사용하여 Post 엔티티를 생성합니다. src/posts/post.entity.ts 파일을 생성하고 다음과 같이 작성합니다:

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

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

                @Column()
                title: string;

                @Column('text')
                content: string;

                @Column()
                createdAt: Date;

                @Column()
                updatedAt: Date;
            }
            
        

2.2 Posts 모듈 및 서비스 생성

Posts 모듈을 생성하고 CRUD 로직을 추가합니다. src/posts/posts.module.tssrc/posts/posts.service.ts 파일을 각각 생성합니다.

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

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

2.3 Posts Controller 생성

PostsController를 생성하여 API 엔드포인트를 정의합니다. src/posts/posts.controller.ts 파일을 다음과 같이 작성합니다:

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

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

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

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

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

2.4 Posts Service 구현하기

최종적으로, PostsService를 구현하여 데이터베이스와의 상호작용을 처리합니다. src/posts/posts.service.ts 파일을 다음과 같이 작성합니다:

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

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

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

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

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

3. Next.js와 API 연동하기

이제 Next.js 애플리케이션에서 Nest.js API를 호출하여 데이터를 가져오고 페이지에 렌더링합니다. 블로그 목록 페이지와 상세 페이지를 구현해 보겠습니다.

3.1 블로그 목록 페이지 생성

블로그 목록 페이지를 생성하여 모든 포스트를 표시합니다. pages/index.js 파일을 다음과 같이 수정합니다:

            
            import { useEffect, useState } from 'react';
            import axios from 'axios';

            const Home = () => {
                const [posts, setPosts] = useState([]);

                useEffect(() => {
                    const fetchData = async () => {
                        const result = await axios('http://localhost:3000/posts');
                        setPosts(result.data);
                    };
                    fetchData();
                }, []);

                return (
                    

블로그 목록

); }; export default Home;

3.2 블로그 상세 페이지 생성

각 포스트의 상세 정보를 보여주기 위해 블로그 상세 페이지를 생성합니다. pages/post/[id].js 파일을 생성하고 다음과 같이 작성합니다:

            
            import { useRouter } from 'next/router';
            import { useEffect, useState } from 'react';
            import axios from 'axios';

            const PostDetail = () => {
                const router = useRouter();
                const { id } = router.query;
                const [post, setPost] = useState(null);

                useEffect(() => {
                    if (id) {
                        const fetchData = async () => {
                            const result = await axios(`http://localhost:3000/posts/${id}`);
                            setPost(result.data);
                        };
                        fetchData();
                    }
                }, [id]);

                if (!post) return 

Loading...

; return (

{post.title}

{post.content}

); }; export default PostDetail;

4. 결론

이번 글에서는 Next.js와 Nest.js를 연동하여 블로그 앱을 만드는 과정을 안내했습니다. Nest.js를 통해 API 서버를 구축하고, Next.js를 사용하여 클라이언트 사이드에서 데이터를 가져와서 렌더링하는 방법을 배웠습니다. 이 과정을 통해 두 프레임워크의 특성을 이해하고, 실전에 어떻게 활용할 수 있는지에 대한 통찰을 얻을 수 있었기를 바랍니다.

여기서 소개한 방법은 기본적인 예제에 불과하며, 실제 프로젝트에서는 좀 더 복잡한 상태 관리, 에러 처리, 팬던시 구현 등을 고려해야 합니다. 여러분의 프로젝트에 맞게 다양한 기능을 추가하고 발전시켜 나가십시오.