Next.js 통합 가이드 - 웹 SDK
GraphQL 은 더 이상 사용되지 않습니다. 자세히 알아보기.
다음 가이드 에서는 Realm 웹 SDK 를 Next.js 에 통합하는 방법을 설명합니다. 애플리케이션. Realm 웹 SDK 를 사용하여 Next.js로 만든 웹 앱과 같은 웹 앱에서 MongoDB Atlas 의 데이터에 액세스 할 수 있습니다. Realm 웹 SDK 는 Atlas App Services 를 통해 MongoDB Atlas 의 데이터와 인터페이스합니다. Next.js는 앱 구성 및 구조를 처리하고 클라이언트 사이드 , 서버 사이드 및 정적 렌더링을 지원하는 React 기반 웹 프레임워크 입니다.
Realm 웹 SDK는 Next.js에서 이러한 모든 렌더링 모드를 지원합니다:
클라이언트 측 렌더링: Atlas GraphQL API 또는 MongoDB 데이터 액세스를 사용하여 브라우저에서 직접 MongoDB를 쿼리합니다.
서버 측 렌더링: 브라우저에서 App Services로 사용자를 인증하고 서버에서 GraphQL API를 사용하여 쿼리합니다.
정적 렌더링: 빌드 시점에 페이지를 생성하기 위해 MondoDB Atlas에서 데이터를 가져옵니다.
시작하기 전에
이 통합 가이드를 사용하기 전에 다음을 수행해야 합니다:
Next.js를 숙지합니다. Next.js 문서를참조하는 것이 좋습니다.
Next.js 앱을 만듭니다. Next.js 애플리케이션을 처음 만드는 경우 Next.js 튜토리얼을 참조하는 것이 좋습니다.
Next.js 앱에 Realm 웹 SDK를 추가합니다. 자세한 내용은 Realm 웹 설치 문서를 참조하십시오.
팁
MongoDB 아틀라스 버셀 통합
Vercel을 사용하여 Next.js 앱을 호스팅하는 경우, MongoDB Atlas 통합을 추가하여 Next.js 앱을 Atlas에 쉽게 연결할 수 있습니다.
인증 추가
앱에서 MongoDB를 쿼리하려면 먼저 App Services클라이언트를 초기화하고 사용자를 인증해야 합니다. 아래 단계에 따라 Realm 웹 SDK를 클라이언트 사이드 Next.js에 연결할 수 있습니다.
이 예시에서는 사용자 정의 React Hook에서 Realm.getApp()을 사용하여 앱 전체에 인증된 Realm.App
인스턴스를 노출하겠습니다.
React Hook을 생성하여 앱 가져오기
클라이언트는 React Hook를 사용하여 앱 ID를 통해 App Services에 연결하는 데 사용하는 Realm.App을 인스턴스화하고 액세스합니다. 이 가이드에서 만드는 페이지 전체에서 해당 후크를 사용하게 됩니다.
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 데이터 액세스 또는 Atlas GraphQL API를 사용하여 MongoDB를 쿼리할 수 있습니다.
MongoDB 데이터 액세스
App
클라이언트가 초기화되고 사용자가 인증되면, MongoDB 데이터 액세스를 사용하여 애플리케이션의 클라이언트 코드에서 직접 MongoDB를 쿼리할 수 있습니다.
App.User.mongoClient() 를 사용하여 app
객체에서 MongoDB 데이터 액세스 인터페이스에 액세스합니다. 그런 다음 이를 사용하여 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/client 를 사용하여 Apollo 클라이언트를 npm 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> ); }
팁
React를 사용하여 GraphQL API로 Atlas를 쿼리하는 방법에 대한 자세한 내용은 Apollo 클라이언트(React) 설명서를 참조하세요.
서버 측 렌더링
이 섹션에서는 Next.js 서버 측 렌더링을 Realm Web SDK 와 통합하는 방법을 보여줍니다. 서버 측 렌더링과 함께 Realm Web SDK 를 사용하면 특정 사용자로 데이터에 액세스할 수 있습니다. 이렇게 하면 해당 사용자 쿼리에 Atlas App Services 규칙 및 권한 을 적용할 수 있습니다.
Next.js 서버에서 직접 MongoDB Atlas를 쿼리하려면 두 가지 구성 요소를 설정해야 합니다: Next.js 서버의 Atlas GraphQL API와 브라우저의 Realm 웹 SDK이며, 이 섹션에서는 두 구성 요소의 설정에 대해 설명합니다.
웹 SDK와 Next.js를 통합하면 다음의 이점이 있습니다.
페이지 로드 시 Atlas에 저장된 데이터에 직접 액세스합니다.
Atlas App Services 규칙 및 권한을 요청에 적용하여 서버 측 코드를 줄입니다.
클라이언트 사이드 JavaScript 사용을 줄입니다.
서버 측 데이터 조작을 수행합니다.
높은 수준에서 Next.js 서버 측 렌더링과 함께 Realm 웹 SDK를 사용하는 프로세스는 다음과 같습니다:
브라우저에서 Atlas App Services 클라이언트의 인스턴스를 만들고 사용자로 로그인합니다. 사용자의 accessToken을 쿠키로 저장합니다. 이 예제에서는 nookies 패키지를 사용합니다. Next.js 앱에서 쿠키 관리를 간소화합니다.
서버에서 'accessToken' 쿠키를 파싱하고, 이를 활용하여 Atlas GraphQL API를 통해 MongoDB에서 데이터를 가져옵니다.
서버에서는 MongoDB의 데이터를 브라우저로 보내기 전에 웹페이지에서 미리 렌더링합니다.
참고
MongoDB 데이터 액세스 시 서버 측 렌더링 사용 지양
서버 측 환경에서 MongoDB Data Access를 사용하여 MongoDB를 쿼리할 수 있지만 일반적으로 권장되지는 않습니다. 모든 요청에서 서버에 전달하기 위해 브라우저에서 사용자 자격 증명을 유지해야 하며, 이는 보안 취약점입니다. MongoDB Data Access는 사용자 객체에서 요청을 수행하는데, 이는 모든 요청 시에 다시 생성하고 인증해야 합니다.
다음 단계는 Next.js 서버 측 렌더링과 함께 Realm 웹 SDK를 사용하는 방법을 설명합니다.
사용자 정의 앱 래퍼(wrapper)를 생성하여 쿠키에 accessToken 추가
사용자 지정 App
페이지 래퍼(wrapper)를 만듭니다. pages/_app.js
파일을 만들고, useApp()
훅으로 Realm.App
을 가져옵니다.
현재 인증된 사용자가 있는 경우 해당 사용자의 accessToken을 쿠키로 저장합니다. 이렇게 하면 요청할 때마다 브라우저에서 서버로 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> ); }
정적 렌더링
Next.js 정적 렌더링을 Realm 웹 SDK와 함께 사용하여 MondoDB Atlas에서 데이터를 가져와 빌드 시점에 페이지 HTML을 생성할 수 있습니다.
다음 사용 사례에서는 정적 렌더링과 함께 Realm 웹 SDK를 사용할 수 있습니다:
콘텐츠 관리 시스템 데이터 가져오기
구성 정보 추가
국제화된 콘텐츠 제작
API 키 생성 및 보호
인증을 위해 Server API Key를 생성해야 합니다. 이 단계를 완료하려면 API 키 구성 페이지의 단계를 따르세요. 그런 다음 Next.js 앱에서 .env.local
파일에 API 키를 추가합니다. 저장된 변수는 PUBLIC_NEXT_
접두사를 붙이지 않는 한 브라우저에서 액세스할 수 없습니다.
REALM_API_KEY=secret_api_key
이제 클라이언트 사이드 렌더링을 제외하고 앱에서 변수에 액세스할 수 있습니다.
const { REALM_API_KEY } = process.env;
을(를) 사용하여 정적 렌더링을 getStaticProps()
수행합니다.
정적 생성 중에 Next.js 함수 getStaticProps() 를 사용하여 MongoDB를 쿼리할 수 있습니다.
getStaticProps()
를 사용하여 페이지를 미리 렌더링하려면 Next.js 앱을 Realm 웹 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 웹 SDK 외에도 다음과 같은 여러 가지 방법으로 Next.js 에서 MongoDB를 쿼리할 수 있습니다.
MongoDB를 Next.js 애플리케이션과 통합한 다음, MongoDB 노드 드라이버를 사용하여 MongoDB 쿼리를 실행합니다. 자세한 내용은 블로그 게시물 MongoDB를 Next.js 앱에 통합하는 방법을 참조하세요. MongoDB 드라이버를 사용하는 것은 Atlas App Services 사용자 기반 규칙 및 권한과 호환되지 않습니다.
MongoDB Atlas Data API 를 사용하여 Next.js 서버에서 MongoDB Atlas 를 쿼리합니다. 자세한 내용은 Atlas 데이터 API 엔드포인트를 참조하세요.