Next.js는 React를 기반으로 구축된 다목적 풀스택 자바스크립트 프레임워크로 JSX, 컴포넌트 및 후크와 같은 주요 기능을 지원합니다. Next.js의 핵심 기능에는 파일 기반 라우팅, JS의 CSS, 서버 측 렌더링 등이 있습니다.

Next.js의 중요한 기능 중 하나는 몽구스와 같은 다양한 백엔드 기술과 원활하게 통합되어 데이터를 효율적으로 쉽게 관리할 수 있다는 것입니다.

Mongoose를 사용하면 Next.js 애플리케이션에서 고성능 REST API를 쉽게 정의하여 MongoDB 데이터베이스에서 데이터를 저장하고 검색할 수 있습니다.

Next.js: 풀스택 자바스크립트 프레임워크

React와 달리 서버 측 렌더링 웹 애플리케이션을 구축하기 위한 완벽한 솔루션을 제공하기 때문에 Next.js는 풀스택 웹 프레임워크로 간주됩니다.

단일 프로젝트 디렉토리에서 애플리케이션의 프론트엔드 및 백엔드 모두에서 작업할 수 있는 기능을 제공하기 때문입니다. 특히 소규모 애플리케이션의 경우 서버 측 기능을 구현하기 위해 별도의 백엔드 프로젝트 폴더를 설정할 필요가 없습니다.

그러나 Next.js가 일부 백엔드 기능을 처리하는 만큼 대규모의 풀스택 애플리케이션을 구축하려면 Express와 같은 전용 백엔드 프레임워크와 결합하는 것이 좋습니다.

Next.js에 풀스택 기능을 제공하는 몇 가지 핵심 기능은 다음과 같습니다:

⭐ 서버 측 렌더링: Next.js는 서버 측 렌더링 기능을 기본으로 지원합니다. 즉, 클라이언트가 서버에 HTTP 요청을 보내면 서버는 요청을 처리하고 브라우저에서 렌더링할 각 페이지에 필요한 HTML 콘텐츠로 응답합니다.

⭐ 라우팅: Next.js는 페이지 기반 라우팅 시스템을 사용하여 타사 라이브러리에 의존하지 않고도 다양한 경로를 정의 및 관리하고, 사용자 입력을 처리하고, 동적 페이지를 생성할 수 있습니다. 또한 새 경로를 추가하는 것은 페이지 디렉터리에 about.js와 같은 새 페이지를 추가하는 것만큼 간단하기 때문에 확장도 쉽습니다.

⭐ API 엔드포인트: Next.js는 HTTP 요청을 관리하고 데이터를 반환하는 API 엔드포인트를 생성하는 데 사용되는 서버 측 기능을 기본적으로 지원합니다. 따라서 Express와 같은 전용 백엔드 프레임워크를 사용하여 별도의 서버를 설정할 필요 없이 백엔드 기능을 쉽게 구축할 수 있습니다. 하지만 Next.js는 주로 프런트엔드 웹 프레임워크라는 점에 유의해야 합니다.

이 글도 확인해 보세요:  녹 매크로: 매크로를 사용하여 코드를 개선하는 방법

MongoDB 데이터베이스 설정

시작하려면 MongoDB 데이터베이스를 설정하세요. 또는 클라우드에서 무료로 MongoDB 클러스터를 구성하여 MongoDB 데이터베이스를 빠르게 스핀업할 수 있습니다. 데이터베이스를 가동하고 실행한 후에는 데이터베이스 연결 URI 문자열을 복사합니다.

이 프로젝트의 코드는 이 GitHub 리포지토리에서 찾을 수 있습니다.

Next.js 프로젝트 설정

새 프로젝트의 디렉터리를 만들고 그 안에 CD를 넣습니다:

 mkdir nextjs-project
cd nextjs-project

Next.js 설치:

 npx create-next-app nextjs-mongodb 

설치 프로세스가 완료되면 종속 요소로 Mongoose를 설치합니다.

 npm install mongoose 

마지막으로 프로젝트의 루트 디렉터리에 데이터베이스 연결 문자열을 저장할 새 .env 파일을 만듭니다.

 NEXT_PUBLIC_MONGO_URI = "database URI connection string" 

데이터베이스 연결 구성

src 디렉터리에 새 폴더를 생성하고 이름을 utils로 지정합니다. 이 폴더 안에 dbConfig.js라는 새 파일을 만들고 다음 코드를 추가합니다:

 import mongoose from 'mongoose';

const connectMongo = async () => mongoose.connect(process.env.NEXT_PUBLIC_MONGO_URI);

export default connectMongo;

데이터 모델 정의

데이터 모델은 데이터 유형 및 데이터 간의 관계를 포함하여 저장될 데이터의 구조를 정의합니다.

MongoDB는 NoSQL 데이터베이스이기 때문에 데이터를 JSON과 유사한 문서로 저장합니다. 몽구스는 Next.js 클라이언트의 데이터를 데이터베이스에서 어떻게 저장하고 액세스해야 하는지 정의하는 방법을 제공합니다.

src 디렉터리에서 모델에 새 폴더와 이름을 만듭니다. 이 폴더 안에 userModel.js라는 새 파일을 생성하고 아래 코드를 추가합니다:

 import { Schema, model, models } from 'mongoose';

const userSchema = new Schema({
  name: String,
  email: {
    type: String,
    required: true,
    unique: true,
  },
});

const User = models.User || model('User', userSchema);

export default User;

API 엔드포인트 생성

다른 프런트엔드 프레임워크와 달리 Next.js는 API 관리를 위한 기본 지원을 제공합니다. 따라서 별도의 서버를 설정하는 대신 Next.js 프로젝트에서 직접 API를 정의할 수 있으므로 API 생성 프로세스가 간소화됩니다.

pages/api 디렉토리 내에서 API 경로를 정의하면 Next.js는 이 디렉토리에 있는 각 파일에 대한 API 엔드포인트를 생성합니다. 예를 들어, userV1/user.js를 생성하면 Next.js는 http://localhost:3000/api/userV1/user 에서 액세스할 수 있는 엔드포인트를 생성합니다.

이 글도 확인해 보세요:  내부에서 REST API 호출을 수행하는 방법 VS 코드

pages/api 내에 새 폴더를 만들고 이름을 userV로 지정합니다. 이 폴더 안에 user.js라는 새 파일을 생성하고 아래 코드를 추가합니다:

 import connectMongo from '../../../utils/dbConfig';
import User from '../../../models/userModel';


/**
 * @param {import('next').NextApiRequest} req
 * @param {import('next').NextApiResponse} res
 */
export default async function userAPI(req, res) {
  try {
    console.log('CONNECTING TO MONGO');
    await connectMongo();
    console.log('CONNECTED TO MONGO');

    if (req.method === 'POST') {
      console.log('CREATING DOCUMENT');
      const createdUser = await User.create(req.body);
      console.log('CREATED DOCUMENT');
      res.json({ createdUser });
    } else if (req.method === 'GET') {
      console.log('FETCHING DOCUMENTS');
      const fetchedUsers = await User.find({});
      console.log('FETCHED DOCUMENTS');
      res.json({ fetchedUsers });
    } else {
      throw new Error(`Unsupported HTTP method: ${req.method}`);
    }
  } catch (error) {
    console.log(error);
    res.json({ error });
  }
}

이 코드는 MongoDB 데이터베이스에서 사용자 데이터를 저장하고 가져오는 API 엔드포인트를 구현합니다. 이 코드는 req와 res라는 두 개의 매개변수를 받는 userAPI 함수를 정의합니다. 이는 각각 들어오는 HTTP 요청과 나가는 HTTP 응답을 나타냅니다.

함수 내부에서 코드는 MongoDB 데이터베이스에 연결하고 들어오는 요청의 HTTP 메서드를 확인합니다.

메소드가 POST 요청인 경우, 코드는 create 메소드를 사용하여 데이터베이스에 새 사용자 문서를 생성합니다. 반대로 GET 요청인 경우 데이터베이스에서 모든 사용자 문서를 가져옵니다.

API 엔드포인트 사용

pages/index.js 파일에 아래 코드를 추가합니다:

⭐ API 엔드포인트에 POST 요청을 보내 데이터베이스에 데이터를 저장합니다.

 import styles from '@/styles/Home.module.css';
import { useState } from 'react';

export default function Home() {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [usersResults, setUsersResults] = useState([]);

  const createUser = async () => {
    try {
      const createdUser = await fetch('/api/userV1/user', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          name,
          email,
        }),
      }).then((res) => res.json());
      console.log('CREATED DOCUMENT');

      setName('');
      setEmail('');

      console.log(createdUser);
    } catch (error) {
      console.log(error);
    }
  };

⭐ GET 엔드포인트에 HTTP 요청을 하여 사용자 데이터를 가져오는 함수를 정의합니다.

 const displayUsers = async () => {
    try {
      console.log('FETCHING DOCUMENTS');
      const fetchedUsers = await fetch('/api/userV1/user').then((res) =>
        res.json()
      );
      console.log('FETCHED DOCUMENTS');
      
      setUsersResults(fetchedUsers);
      console.log(usersResults)
  
    } catch (error) {
      console.log(error);
    }
  };

이 글도 확인해 보세요:  자바스크립트에서 Intl API를 사용하는 방법

⭐ 마지막으로 텍스트 입력 필드와 제출 및 사용자 데이터 버튼이 있는 양식 요소를 렌더링하고 표시합니다.

   return (
    <>
      <main className={styles.main}>
        <div className={styles.description}>
          <div className={styles.form}>
            <label>
              Name:
              <input type="text" value={name} onChange={(e) => { setName(e.target.value)}} />
            </label>
            <label>
              Email:
              <input type="email" value={email} onChange={(e) => { setEmail(e.target.value) }} />
            </label>
            <button onClick={createUser}>Submit data</button>
          </div>

          <div>
            <button onClick={displayUsers}> Display user Data</button>
            <div className={styles.description}>
                {usersResults.fetchedUsers && usersResults.fetchedUsers.length > 0 && (
                  <ul>
                    {usersResults.fetchedUsers.map((user) => (
                    <li key={user._id}>
                      <p>{user.name}</p>
                      <p>({user.email})</p>
                    </li>
                  ))}
                </ul>
              )}
            </div>
          </div>
        </div>
      </main>
    </>
  );
}

마지막으로, 개발 서버를 스핀업하여 변경 사항을 업데이트하고 브라우저에서 http://localhost:3000 로 이동합니다.

 npm run dev 

애플리케이션에서 Next.js 사용

Next.js는 사이드 프로젝트든 대규모 웹 솔루션이든 상관없이 멋진 웹 애플리케이션을 구축하는 데 환상적인 옵션입니다. 성능과 확장성이 뛰어난 제품을 만드는 과정을 간소화하는 다양한 기능을 제공합니다.

주로 강력한 클라이언트 측 프레임워크이지만 서버 측 기능을 활용하여 백엔드 서비스를 빠르게 가동할 수도 있습니다.

By 이지원

상상력이 풍부한 웹 디자이너이자 안드로이드 앱 마니아인 이지원님은 예술적 감각과 기술적 노하우가 독특하게 조화를 이루고 있습니다. 모바일 기술의 방대한 잠재력을 끊임없이 탐구하고, 최적화된 사용자 중심 경험을 제공하기 위해 최선을 다하고 있습니다. 창의적인 비전과 뛰어난 디자인 역량을 바탕으로 All Things N의 잠재 독자가 공감할 수 있는 매력적인 콘텐츠를 제작합니다.