Docs Menu
Docs Home
/ /
Atlas Device SDK
/

Next.js 統合ガイド - Web SDK

項目一覧

  • 始める前に
  • 認証を追加する
  • クライアント側レンダリング
  • サーバーサイド レンダリング
  • 静的レンダリング
  • Next.js から MongoDB をクエリする別の方法

次のガイドでは、 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 からデータを取得して、構築時にページを生成します。

この統合ガイドを使用する前に、次の操作を行う必要があります。

Tip

MongoDB Atlas Vercel 統合

Vercel を使用して Next.js アプリをホストしている場合は、 MongoDB Atlas 統合 を追加して、Next.js アプリを Atlas に簡単に接続できます。

Vercel MongoDB Atlas 統合の詳細については、こちらを参照してください。

アプリから MongoDB をクエリする前に、App Services クライアントを初期化し、ユーザーを認証する必要があります。 Realm Web SDK をクライアント側の Next.js に接続するには、以下の手順に従います。

この例では、カスタム React フックでRealm.getApp()を使用して、認証された Realm.Appインスタンスをアプリ全体で公開します。

Tip

以下も参照してください。

アプリケーション全体で Realm 認証を公開する追加の方法については、 Next.js 認証ドキュメント を参照してください。

1

アプリ IDを使用して、Next.js アプリを Atlas App Services に接続します。 次の操作を行い、アプリ全体のアプリ ID を環境変数として公開します。

  1. アプリ ID を見つけます。

  2. プロジェクトのルート ディレクトリにファイル.env.localを作成します。

  3. アプリ ID の環境変数を追加します。 サーバーだけでなくブラウザからアプリ ID にアクセスできるようにするには、名前の前にNEXT_PUBLIC_を付けます。

.env.local
NEXT_PUBLIC_APP_ID=<YOUR App Services App ID>
2

クライアントは React フックを使用してRealm.Appをインスタンス化し、App ID を使用して App Services に接続するために使用します。 このガイドで作成するページ全体でこのフックを使用します。

  1. ファイルcomponents/useApp.jsを作成します。

  2. 次のコードを追加して、 Appインスタンスをインスタンス化してアクセスします。

operations/useApp.js
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;
}
3

これで、 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 認証ドキュメント を参照してください。

Tip

以下も参照してください。

このセクションでは、Next.js のクライアント側レンダリングを Realm Web SDK と統合する方法を説明します。 これらの手順に従って、MongoDB を直接クエリし、Next.js アプリケーションのクライアント側 JavaScript を介して Atlas App Services サーバーレス バックエンドと交流できます。 MongoDB Data AccessまたはAtlas GraphQL API を使用して 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 を使用して、Next.js クライアント側コードから GraphQL 経由で MongoDB をクエリすることもできます。

この例では、 Apollo GraphQL クライアント を使用します をクリックして、GraphQL クエリを実行するようにします。Apollo クライアントをnpm パッケージ @apollo/client とともにインストール とそのピア 依存関係GraphQL 。

npm install @apollo/client graphql

GraphQL クエリを実行するためのページを追加できるようになりました。 ページのコードでは、次の処理が行われます。

  1. 必要な依存関係をインポートします

  2. プロバイダー コンポーネントに GraphQL クライアントを作成します。

  3. GraphQL クエリを定義します。

  4. GraphQL プロバイダーを消費し、クエリを実行するコンポーネントを作成します。

  5. コンシューマー コンポーネントをラップするプロバイダー コンポーネントをエクスポートします。

全体で、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 サーバーサイド レンダリングを使用するプロセスは次のようになります。

  1. ブラウザで、App Services クライアントのインスタンスを作成し、ユーザーをログインします。 ユーザーの accessToken を クッキー として保存します。 この例では、パッケージ クッキー を使用します は、Next.js アプリでのクッキー管理を簡素化します。

  2. サーバー上で accessToken クッキーを解析し、それを使用して Atlas GraphQL API を使用して MongoDB からデータを取得します。

  3. サーバー上で、ブラウザに送信する前に、ウェブページの MongoDB からのデータを事前にレンダリングします。

注意

サーバー側のレンダリングで MongoDB Data Access を使用しない

サーバーサイドの環境で MongoDB Data Access を使用して MongoDB をクエリすることも可能ですが、一般的には推奨されません。 リクエストごとにサーバーに渡すには、ブラウザ内にユーザー認証情報を保持する必要があるため、セキュリティ上の脆弱性があります。 さらに、MongoDB Data Access はユーザー オブジェクトからリクエストを行います。このオブジェクトは、リクエストごとに再インスタンス化と再認証を行う必要があります。

次の手順では、Realm Web SDK と Next.js サーバーサイド レンダリングの使用方法の概要を説明します。

1

次の npm パッケージをインストールします。

npm install nookies
npm install @apollo/client graphql
2

カスタム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;
3

サーバー側レンダリングを実行するための新しいページ ファイルを作成します。 ページで、次の操作を実行するコードを追加します。

  1. 関連する依存関係をインポートします。

  2. ユーザーの現在の認証トークンを使用して、すべてのリクエストでサーバー側の GraphQL クライアントを作成する関数を追加します。

  3. サーバーがデータを取得するために使用する GraphQL リクエストを作成します。

  4. Next.js getServerSideProps の使用 関数を使用して、次の操作を実行します。

    1. クッキーからアクセス トークンを解析します。

    2. アクセス トークンを使用して GraphQL クライアントを作成します。

    3. GraphQL クエリを実行します。

    4. サーバー側レンダリングで使用するデータを返します。

  5. ページ コンポーネントをエクスポートしてデータをレンダリングします。

以上をまとめて、サーバー側のレンダリング ページは次のようになります。

// 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 を使用することをお勧めします。

  • コンテンツ管理システム データを取り込む

  • 構成情報を追加します

  • 国際化されたコンテンツの作成

1

認証用のサーバー API キーを作成する必要があります。 このステップを完了するには、 API キー構成 ページの手順に従ってください。 次に、Next.js アプリで、 .env.localファイルに API キーを追加します。 保存された変数は、先頭にPUBLIC_NEXT_を付けない限り、ブラウザからはアクセスできません

.env.local
REALM_API_KEY=secret_api_key

これで、クライアント側のレンダリングを除く、アプリ内の 変数にアクセスできるようになります。

const { REALM_API_KEY } = process.env;
2

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>
);
}

Realm Web SDK に加えて、Next.js からいくつかの方法で MongoDB をクエリできます。

戻る

Apollo GraphQL Client(React)