ウェブサイト検索

Next.js データ管理: Mongoose を使用した MongoDB データの保存と取得


Mongoose の能力と、Mongoose を使用して単純な Web アプリのデータを管理する方法を学びましょう。

Next.js は、React 上に構築された多用途のフルスタック JavaScript フレームワークで、JSX、コンポーネント、フックなどの主要な機能をサポートしています。 Next.js の中核機能には、ファイルベースのルーティング、JS 内の CSS、サーバーサイド レンダリングなどがあります。

Next.js の重要な機能の 1 つは、Mongoose などのさまざまなバックエンド テクノロジとシームレスに統合できることで、データを簡単に効率的に管理できるようになります。

Mongoose を使用すると、Next.js アプリケーションからパフォーマンスの高い REST API を簡単に定義して、MongoDB データベースにデータを保存したり、そこからデータを取得したりできます。

Next.js: フルスタック JavaScript フレームワーク

React とは異なり、Next.js はサーバー側でレンダリングされる Web アプリケーションを構築するための完全なソリューションを提供するため、フルスタック Web フレームワークとみなされます。

これは、単一のプロジェクト ディレクトリからアプリケーションのフロントエンドとバックエンドの両方で作業できる機能を提供するためです。特に小規模なアプリケーションの場合、サーバー側の機能を実装するために、必ずしも別のバックエンド プロジェクト フォルダーを設定する必要はありません。

ただし、Next.js は一部のバックエンド機能を処理しますが、大規模なフルスタック アプリケーションを構築するには、Express のような専用のバックエンド フレームワークと組み合わせることをお勧めします。

Next.js にフルスタック機能を提供するコア機能には、次のようなものがあります。

  • サーバー側レンダリング: Next.js は、サーバー側レンダリング機能の組み込みサポートを提供します。基本的に、クライアントが HTTP リクエストをサーバーに送信すると、サーバーはそのリクエストを処理し、ブラウザ上で表示される各ページに必要な HTML コンテンツで応答することを意味します。
  • ルーティング: Next.js はページベースのルーティング システムを使用して、サードパーティのライブラリに依存することなく、さまざまなルートを定義および管理し、ユーザー入力を処理し、動的ページを作成します。さらに、新しいルートの追加は、about.js などの新しいページをページのディレクトリに追加するのと同じくらい簡単なので、スケールアップも簡単です。
  • API エンドポイント: Next.js は、HTTP リクエストを管理してデータを返す API エンドポイントの作成に使用されるサーバー側機能の組み込みサポートを提供します。これにより、Express のような専用のバックエンド フレームワークを使用して別のサーバーをセットアップすることなく、バックエンド機能を簡単に構築できるようになります。ただし、Next.js は主にフロントエンド Web フレームワークであることに注意することが重要です。

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 のようなドキュメントに保存します。 Mongoose は、Next.js クライアントからのデータをどのように保存し、データベースからアクセスするかを定義する方法を提供します。

src ディレクトリに新しいフォルダーを作成し、models に名前を付けます。このフォルダー内に、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 にアクセスできるエンドポイントを作成します。

pages/api 内に新しいフォルダーを作成し、userV1 という名前を付けます。このフォルダー内に、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 エンドポイントを実装します。これは、reqres の 2 つのパラメータを取る userAPI 関数を定義します。これらはそれぞれ受信 HTTP リクエストと送信 HTTP 応答を表します。

関数内で、コードは MongoDB データベースに接続し、受信リクエストの HTTP メソッドをチェックします。

メソッドが POST リクエストの場合、コードは作成 メソッドを使用してデータベースに新しいユーザー ドキュメントを作成します。逆に、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);
        }
      };
  • 最後に、テキスト入力フィールドを含むフォーム要素をレンダリングし、ユーザー データ ボタンを送信して表示します。

      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 は、サイド プロジェクトで作業している場合でも、大規模な Web ソリューションで作業している場合でも、クールな Web アプリケーションを構築するための素晴らしいオプションです。パフォーマンスとスケーラブルな製品を作成するプロセスを合理化するさまざまな機能を提供します。

これは主に堅牢なクライアント側のフレームワークですが、サーバー側の機能を利用してバックエンド サービスを迅速に起動することもできます。

関連記事: