Next.js 統合ガイド - Web SDK
GraphQL は非推奨です。 詳細はこちら。
次のガイドでは、 Realm Web SDKを Next.js に統合する方法について説明します。 アプリケーション。 Realm Web SDKを使用すると、Next.js で作成されたようなウェブ アプリからMongoDB Atlasのデータにアクセスできます。 Realm Web SDKは、Atlas App Services 経由でMongoDB Atlasのデータとインターフェースします。 Next.js は、アプリの構成と構造を処理し、クライアント側、サーバー側、および静的レンダリングをサポートする React ベースの Webフレームワークです。
Realm Web SDK は、Next.js で次のレンダリング モードをすべてサポートしています。
クライアント側レンダリング: Atlas GraphQL API または MongoDB Data Access を使用して、ブラウザから直接 MongoDB をクエリします。
サーバーサイド レンダリング: ブラウザから App Services でユーザーを認証し、サーバー上で GraphQL API を使用してクエリを実行します
静的レンダリング: MongoDB Atlas からデータを取得して、構築時にページを生成します。
始める前に
この統合ガイドを使用する前に、次の操作を行う必要があります。
Next.js について理解します。 Next.js ドキュメントの参照を検討してください。
Next.js アプリの作成 Next.js アプリケーションを初めて作成する場合は、次の .js チュートリアルを参照してください。
Next.js アプリに Realm Web SDK を追加します。 詳細については、 Realm Web インストールのドキュメントを参照してください。
Tip
MongoDB Atlas Vercel 統合
Vercel を使用して Next.js アプリをホストしている場合は、 MongoDB Atlas 統合 を追加して、Next.js アプリを Atlas に簡単に接続できます。
認証を追加する
アプリから MongoDB をクエリする前に、App Services クライアントを初期化し、ユーザーを認証する必要があります。 Realm Web SDK をクライアント側の Next.js に接続するには、以下の手順に従います。
この例では、カスタム React フックでRealm.getApp()を使用して、認証された Realm.App
インスタンスをアプリ全体で公開します。
アプリを取得するための React フックの作成
クライアントは React フックを使用してRealm.Appをインスタンス化し、App ID を使用して App Services に接続するために使用します。 このガイドで作成するページ全体でこのフックを使用します。
ファイル
components/useApp.js
を作成します。次のコードを追加して、
App
インスタンスをインスタンス化してアクセスします。
import { useEffect, useState } from "react"; import * as Realm from "realm-web"; export function useApp() { const [app, setApp] = useState(null); // Run in useEffect so that App is not created in server-side environment useEffect(() => { setApp(Realm.getApp(process.env.NEXT_PUBLIC_APP_ID)); }, []); return app; }
ユーザーをログインさせ
これで、 useApp()
フックを使用してapp
インスタンスにアクセスし、それを使用してユーザーをログインできるようになります。 ユーザーがアプリのホームページにアクセスしたときに、 pages/index.js
で匿名で認証します。
import { useEffect } from "react"; import * as Realm from "realm-web"; import Link from "next/link"; import { useApp } from "../components/useApp"; export default function Home() { const app = useApp(); // note: useEffect runs in the browser but does not run during server-side rendering useEffect(() => { // If no logged in user, log in if (app && !app.currentUser) { const anonymousUser = Realm.Credentials.anonymous(); app.logIn(anonymousUser); } }, [app, app?.currentUser]); return ( //Your app ); }
実際のアプリケーションでは、より複雑な認証フローが必要になります。 詳細については、 Next.js 認証ドキュメント を参照してください。
クライアント側レンダリング
このセクションでは、Next.js のクライアント側レンダリングを Realm Web SDK と統合する方法を説明します。 これらの手順に従って、MongoDB を直接クエリし、Next.js アプリケーションのクライアント側 JavaScript を介して Atlas App Services サーバーレス バックエンドと交流できます。 MongoDB Data AccessまたはAtlas GraphQL API を使用して MongoDB をクエリできます。
MongoDB データアクセス
App
クライアントが初期化され、ユーザーが認証されると、MongoDB Data Access を使用して、アプリケーション内のクライアント コードから MongoDB を直接クエリできます。
App.User.mongoClient()を使用してapp
オブジェクトから MongoDB Data Access インターフェースにアクセスします。 後、それを使用して MongoDB をクエリします。
import { useEffect, useState } from "react"; import { useApp } from "../components/useApp"; function MongoDbDataAccess({ name }) { const [plant, setPlant] = useState(); const app = useApp(); useEffect(() => { if (app?.currentUser) { const mongo = app?.currentUser?.mongoClient("mongodb-atlas"); const plants = mongo.db("example").collection("plants"); plants.findOne({ name }).then((foundPlant) => { setPlant(foundPlant); }); } }, [app, app?.currentUser, app?.currentUser?.id, name]); return ( <div> <h1>Data from MongoDB Access</h1> {plant ? ( <div> <p>{plant.name}</p> <p>{plant.color}</p> </div> ) : ( "no plant" )} </div> ); } export default function DaffodilInformation() { return <MongoDbDataAccess name="daffodil" />; }
Atlas GraphQL API
あるいは、Atlas GraphQL API を使用して、Next.js クライアント側コードから GraphQL 経由で MongoDB をクエリすることもできます。
この例では、 Apollo GraphQL クライアント を使用します をクリックして、GraphQL クエリを実行するようにします。Apollo クライアントをnpm パッケージ @apollo/client とともにインストール とそのピア 依存関係GraphQL 。
npm install @apollo/client graphql
GraphQL クエリを実行するためのページを追加できるようになりました。 ページのコードでは、次の処理が行われます。
必要な依存関係をインポートします
プロバイダー コンポーネントに GraphQL クライアントを作成します。
GraphQL クエリを定義します。
GraphQL プロバイダーを消費し、クエリを実行するコンポーネントを作成します。
コンシューマー コンポーネントをラップするプロバイダー コンポーネントをエクスポートします。
全体で、GraphQL ページは次のようになります。
// 1. Import dependencies import { ApolloClient, ApolloProvider, HttpLink, InMemoryCache, useQuery, gql, } from "@apollo/client"; import { useApp } from "../components/useApp"; // 2. Add GraphQL client provider function GraphQLProvider({ children }) { const app = useApp(); const client = new ApolloClient({ link: new HttpLink({ uri: process.env.NEXT_PUBLIC_GRAPHQL_API_ENDPOINT, // We get the latest access token on each request fetch: async (uri, options) => { const accessToken = app.currentUser?.accessToken; options.headers.Authorization = `Bearer ${accessToken}`; return fetch(uri, options); }, }), cache: new InMemoryCache(), }); return <ApolloProvider client={client}>{children}</ApolloProvider>; } // 3. GraphQL query const GET_PLANT = gql` query Plant($name: String!) { plant(query: { name: $name }) { _id sunlight name color type _partition } } `; // 4. Consumer of provider and query function PlantInformation({ name }) { const { loading, error, data } = useQuery(GET_PLANT, { variables: { name }, }); if (loading || !data) return <p>Loading ...</p>; if (error) console.error("Failed with error:", error); return ( <div> {data.plant ? ( <div> <p>{data.plant.name}</p> <p>{data.plant.color}</p> </div> ) : ( "no plant" )} </div> ); } // 5. Export page with the GraphQL query export default function FullGraphQLPage() { return ( <GraphQLProvider> <PlantInformation name="daffodil" /> </GraphQLProvider> ); }
Tip
React で GraphQL API を使用して Atlas をクエリする方法の詳細については、 Apollo Client(React)ドキュメント を参照してください。
サーバーサイド レンダリング
このセクションでは、Next.js サーバーサイド レンダリングを Realm Web SDK と統合する方法を説明します。 Realm Web SDK とサーバー側レンダリングを組み合わせて使用すると、個別のユーザーとしてデータにアクセスできます。 そのためには、それらのユーザー クエリにApp Services ルールと権限を適用します。
Next.js サーバーから MongoDB Atlas を直接クエリするには、Next.js サーバー上の Atlas GraphQL API と、ブラウザ内の Realm Web SDK の 2 つの異なるコンポーネントを設定する必要があります。このセクションでは、両方の設定について説明します。
Web SDK と Next.js を統合することをお勧めします。これにより、次のことが可能になります。
ページロード時に Atlas に保存されているデータに直接アクセスします。
リクエストに Atlas App Services のルールと権限を適用して、サーバー側のコードを削減します。
クライアント側 JavaScript の使用を減らします。
サーバー側でのデータ操作を実行します。
高レベルでは、Realm Web SDK と Next.js サーバーサイド レンダリングを使用するプロセスは次のようになります。
ブラウザで、App Services クライアントのインスタンスを作成し、ユーザーをログインします。 ユーザーの accessToken を クッキー として保存します。 この例では、パッケージ クッキー を使用します は、Next.js アプリでのクッキー管理を簡素化します。
サーバー上で accessToken クッキーを解析し、それを使用して Atlas GraphQL API を使用して MongoDB からデータを取得します。
サーバー上で、ブラウザに送信する前に、ウェブページの MongoDB からのデータを事前にレンダリングします。
注意
サーバー側のレンダリングで MongoDB Data Access を使用しない
サーバーサイドの環境で MongoDB Data Access を使用して MongoDB をクエリすることも可能ですが、一般的には推奨されません。 リクエストごとにサーバーに渡すには、ブラウザ内にユーザー認証情報を保持する必要があるため、セキュリティ上の脆弱性があります。 さらに、MongoDB Data Access はユーザー オブジェクトからリクエストを行います。このオブジェクトは、リクエストごとに再インスタンス化と再認証を行う必要があります。
次の手順では、Realm Web SDK と Next.js サーバーサイド レンダリングの使用方法の概要を説明します。
クッキーにアクセストークンを追加するためのカスタムアプリラッパーを作成します
カスタムApp
ページ ラッパーを作成します。 ファイルpages/_app.js
を作成し、 useApp()
フックを使用してRealm.App
インスタンスを取得します。
現在認証されているユーザーが存在する場合は、accessToken をクッキーとして保存します。 これにより、リクエストごとにアクセストークンがブラウザからサーバーに転送されます。 以下に示すように、ユーザー オブジェクトに変更があるたびに実行されるuseEffect
フックにクッキーを設定します。 このsetInterval
は、トークンの有効期限が切れる前に、クッキーの認証情報もリセットします。
import { useApp } from "../components/useApp"; import { setCookie } from "nookies"; // Import the useEffect hook import { useEffect } from "react"; function MyApp({ Component, pageProps }) { const app = useApp(); // Reset the user access token in cookies on a regular interval useEffect(() => { const user = app?.currentUser; if (user) { setCookie(null, "accessToken", user.accessToken); // Refresh token before session expires const TWENTY_MIN_MS = 1200000; const resetAccessToken = setInterval(async () => { await app?.currentUser?.refreshCustomData(); setCookie(null, "accessToken", user.accessToken); }, TWENTY_MIN_MS); // Clear interval setting access token whenever component unmounts or // there's a change in user. return () => clearInterval(resetAccessToken); } }, [app, app?.currentUser]); return ( <> <Component {...pageProps} app={app} /> </> ); } export default MyApp;
サーバー側でのデータのレンダリング
サーバー側レンダリングを実行するための新しいページ ファイルを作成します。 ページで、次の操作を実行するコードを追加します。
関連する依存関係をインポートします。
ユーザーの現在の認証トークンを使用して、すべてのリクエストでサーバー側の GraphQL クライアントを作成する関数を追加します。
サーバーがデータを取得するために使用する GraphQL リクエストを作成します。
Next.js getServerSideProps の使用 関数を使用して、次の操作を実行します。
クッキーからアクセス トークンを解析します。
アクセス トークンを使用して GraphQL クライアントを作成します。
GraphQL クエリを実行します。
サーバー側レンダリングで使用するデータを返します。
ページ コンポーネントをエクスポートしてデータをレンダリングします。
以上をまとめて、サーバー側のレンダリング ページは次のようになります。
// 1. import dependencies import nookies from "nookies"; import { ApolloClient, InMemoryCache, HttpLink, gql } from "@apollo/client"; // 2. Function to create GraphQL client const createClient = (token) => new ApolloClient({ link: new HttpLink({ ssrMode: true, uri: process.env.NEXT_PUBLIC_GRAPHQL_API_ENDPOINT, headers: { Authorization: `Bearer ${token}`, }, }), cache: new InMemoryCache(), }); // 3. GraphQL Query used in SSR const GET_PLANT = gql` query Plant($name: String!) { plant(query: { name: $name }) { _id sunlight name color type _partition } } `; // 4. Server-side logic to parse cookie and run query export async function getServerSideProps(context) { const { accessToken } = nookies.get(context); const client = createClient(accessToken); const { data: { plant: lily }, } = await client.query({ query: GET_PLANT, variables: { name: "daffodil" }, }); return { props: { lily }, }; } // Full page exported that gets the data from SSR export default function Ssr({ lily }) { return ( <div> <h1>Data from Server-Side Rendering</h1> {lily ? ( <div> <p>{lily.name}</p> <p>{lily.color}</p> </div> ) : ( "no plant" )} </div> ); }
静的レンダリング
Realm Web SDK で Next.js の静的レンダリングを使用して、MongoDB Atlas からデータを取得し、構築時にページ HTML を生成できます。
次のユースケースでは、静的レンダリングとともに Realm Web SDK を使用することをお勧めします。
コンテンツ管理システム データを取り込む
構成情報を追加します
国際化されたコンテンツの作成
getStaticProps()
を使用して静的レンダリングを実行します。
Next.js 関数 getStaticProps() を使用できます 静的生成中に MongoDB をクエリします。
getStaticProps()
を使用してページを事前にレンダリングするには、Next.js アプリを Realm Web SDK に接続します。 次に、 getStaticProps()
を使用して MongoDB からデータを取得できます。 次の例は、静的レンダリングを使用して MongoDB をクエリする方法を示しています。
import * as Realm from "realm-web"; export async function getStaticProps() { const apiKey = process.env.REALM_API_KEY; const app = new Realm.App({ id: process.env.NEXT_PUBLIC_APP_ID }); // Log in user using realm API key const credentials = Realm.Credentials.apiKey(apiKey); const user = await app.logIn(credentials); // Connect to database const mongo = user.mongoClient("mongodb-atlas"); const plants = mongo.db("example").collection("plants"); // Use plants.findOne to query the database const data = await plants.findOne({ name: "daffodil" }); // You must parse data as JSON to use it as a prop const json = JSON.parse(JSON.stringify(data)); return { props: { plant: json, }, }; } export default function Static({ plant }) { return ( <div> <h1>Data from Static Rendering</h1> <div> <div> <p>{plant.name}</p> <p>{plant.color}</p> </div> </div> </div> ); }
Next.js から MongoDB をクエリする別の方法
Realm Web SDK に加えて、Next.js からいくつかの方法で MongoDB をクエリできます。
MongoDB を Next.js アプリケーションと統合し、MongoDB Node ドライバーを使用して MongoDB クエリを実行します。 詳細については、ブログ記事「 MongoDB を Next.js アプリに統合する方法 」を参照してください。 MongoDB ドライバーの使用は、App Servicesユーザーベースのルールと権限と互換性がありません。
MongoDB Data API を使用して、Next.js サーバーから MongoDB Atlas をクエリします。 詳細については、 「データAPI エンドポイント」 を参照してください。