La siguiente guía explica cómo integrar el SDK web de Realm en un Next.js Aplicación. Puede usar el SDK web de Realm para acceder a datos en MongoDB Atlas desde aplicaciones web, como las creadas con Next.js. El SDK web de Realm interactúa con sus datos en MongoDB Atlas a través de Atlas App Services. Next.js es un framework web basado en React que gestiona la configuración y la estructura de las aplicaciones y admite renderizado estático, del lado del cliente y del servidor.
El Realm Web SDK soporta todos estos modos de renderizado en Next.js:
Client-side rendering: Query MongoDB directly from the browser using the Atlas GraphQL API or MongoDB Data Access.
Renderización del lado del servidor: Autentica a los usuarios con App Services desde el navegador y realiza consultas usando la GraphQL API en el servidor
Static rendering: Fetch data from MondoDB Atlas to generate pages at build time.
Antes de comenzar
Antes de utilizar esta guía de integración, debes:
Be familiar with Next.js. Consider referring to the Next.js documentation.
Create a Next.js app. If creating a Next.js application for the first time, consider referring to the Next.js Tutorial.
Agrega el SDK web de Realm en tu aplicación de Next.js. Para ver más información, consulta la documentación de instalación de Realm Web.
Tip
MongoDB Atlas Vercel Integration
If you're using Vercel to host your Next.js app, add the MongoDB Atlas integration to easily connect your Next.js app to Atlas.
Agregar autenticación
Antes de poder hacer query MongoDB desde tu aplicación, debes inicializar el cliente de App Services y autenticar a un usuario. Puedes seguir los siguientes pasos para conectar el SDK web de Realm al lado del cliente de Next.js.
En este ejemplo, vamos a exponer un servidor autenticado. Realm.App instancia en toda la aplicación usando Realm.getApp() en un React Hook personalizado.
Tip
Para otras maneras de habilitar Realm Authentication en toda tu aplicación, consulta la documentación oficial de autenticación de Next.js.
Agrega una variable de entorno ID de la aplicación
Use the App ID to connect the Next.js app to Atlas App Services. Expose the App ID throughout the app as an environment variable by doing the following:
Create the file
.env.localin the project's root directory.Agregar una variable de entorno para el ID de la aplicación. Para hacer que el ID de la aplicación sea accesible desde el navegador además del servidor, antepón su nombre con
NEXT_PUBLIC_.
NEXT_PUBLIC_APP_ID=<YOUR App Services App ID>
Crear un React Hook para obtener la aplicación
The client uses a React Hook to instantiate and access the Realm.App, which you use to connect to App Services using the App ID. You will use this hook throughout the pages you create in this guide.
Create the file
components/useApp.js.Agregue el siguiente código para crear una instancia y acceder a la instancia
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; }
Log the user in
Now you can access the app instance with the useApp() hook, and use it to log a user in. Authenticate anonymously in pages/index.js when a user arrives to the app home page.
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 ); }
In a real application, you would want to have a more complex authentication flow. For more information, refer to the Next.js authentication documentation.
Renderizado del lado del cliente
Esta sección muestra cómo puedes integrar la renderización lado del cliente de Next.js con el Realm Web SDK. Siguiendo estos pasos, puedes directamente query MongoDB y tener una interacción con un backend sin servidor de Atlas App Services mediante JavaScript del lado del cliente en tu aplicación Next.js. Puedes consultar MongoDB usando acceso a los datos de MongoDB o la API de Atlas GraphQL.
MongoDB Data Access
Once the App client is initialized and a user is authenticated, you can use MongoDB Data Access to query MongoDB directly from client code in your application.
Acceda a la interfaz de acceso a los datos de MongoDB desde el objeto app con App.User.mongoClient(), y luego utilizarlo para realizar query a 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
Alternatively, you can use the Atlas GraphQL API to query MongoDB via GraphQL from Next.js client-side code.
This example uses the Apollo GraphQL client to execute GraphQL queries. Install the Apollo client with its npm package @apollo/client and its peer dependency graphql.
npm install @apollo/client graphql
Ahora puedes añadir una página para realizar GraphQL queries. El código en la página realiza lo siguiente:
Importa las dependencias necesarias
Crea el cliente GraphQL en un componente proveedor.
Defines the GraphQL query.
Creates a component that consumes the GraphQL provider and runs the query.
Exporta el componente del proveedor que envuelve al componente consumidor.
All together, the GraphQL page should look as follows:
// 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
Para obtener más información sobre cómo consultar Atlas con la GraphQL API y React, consulta la documentación de Apollo cliente (React).
Renderizado del lado del servidor
This section shows how you can integrate Next.js server-side rendering with the Realm Web SDK. Using the Realm Web SDK with server-side rendering allows you to access data as a specific user. In doing so, you apply App Services Rules and Permissions to those user queries.
Para consultar MongoDB Atlas directamente desde el servidor Next.js, debes configurar dos componentes distintos: la API GraphQL de Atlas en el servidor Next.js y el SDK web de Realm en el navegador. Esta sección explica la configuración de ambos.
Es posible que desee integrar el SDK web y Next.js porque le permite:
Accede a los datos almacenados en Atlas directamente al cargar la página.
Aplique reglas y permisos de Atlas App Services a las solicitudes para reducir el código del lado del servidor.
Reduce use of client-side JavaScript.
Realizar la manipulación de datos del lado del servidor.
On a high level, the process for using the Realm Web SDK with Next.js server-side rendering is as follows:
In the browser, create a instance of your App Services client and log in a user. Save the user's accessToken as a cookie. This examples uses the package nookies, which simplifies cookie management in a Next.js app.
En el servidor, se analiza la cookie accessToken y se usa para obtener datos de MongoDB usando la API de Atlas GraphQL.
On the server, pre-render the data from MongoDB in your webpage before sending it to the browser.
Nota
No utilizar el acceso a los datos de MongoDB con renderizado del lado del servidor
While possible to use the MongoDB Data Access in server-side environments to query MongoDB, it is not generally advisable. You would need to persist user credentials in the browser to pass to the server on every request, which is a security vulnerability. Plus, MongoDB Data Access makes requests from a user object, which would need to be re-instantiated and re-authenticated on every request.
Los siguientes pasos describen el uso del SDK web de Realm con la representación del lado del servidor de Next.js.
Crea un contenedor de aplicación personalizado para añadir accessToken a las cookies
Create a custom App page wrapper. Create the file pages/_app.js, and get the Realm.App instance with the useApp() hook.
If there is a user currently authenticated, save their accessToken as a cookie. This transfers the accessToken from the browser to the server on every request. Set your cookie in a useEffect hook that runs every time there's a change in the user object, as shown below. The setInterval also resets the credential in cookies before the token expires.
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;
Server-side render the data
Create a new page file to perform the server-side rendering. On the page, add code to perform the following:
Importe las dependencias relevantes.
Agregue una función que cree un cliente GraphQL del lado del servidor en cada solicitud con el token de autenticación actual del usuario.
Crea la solicitud GraphQL que el servidor utiliza para obtener datos.
Use the Next.js getServerSideProps function to perform the following:
Parse access token from cookies.
Create a GraphQL client with the access token.
Ejecute la consulta GraphQL.
Return data to be used in the server-side render.
Export the page component to render the data.
All together, the server-side rendering page looks as follows:
// 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> ); }
Representación estática
You can use Next.js static rendering with the Realm Web SDK to pull data from MondoDB Atlas and generate page HTML at build time.
You might want to use the Realm Web SDK with static rendering for the following use cases:
Extraer datos del sistema de gestión de contenido
Add configuration information
Crear contenido internacionalizado
Creating and guarding your API key
You need to create a Server API key for authentication. Follow the steps on the API Key Configuration page to complete this step. Then, in your Next.js app, add the API key to your .env.local file. The variable stored is not accessible from the browser, as long as you do not prefix it with PUBLIC_NEXT_.
REALM_API_KEY=secret_api_key
Now you can access the variable in your app, except for in client-side rendering.
const { REALM_API_KEY } = process.env;
Realizar representación estática getStaticProps() con.
You can use the Next.js function getStaticProps() to query MongoDB during static generation.
In order to pre-render your page using getStaticProps(), connect your Next.js app to the Realm Web SDK. Then, you can use getStaticProps() to fetch data from MongoDB. The following example shows how to query MongoDB with static rendering.
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> ); }
Formas alternativas de query MongoDB desde siguiente.js
Además del SDK de Realm Web, puedes consultar MongoDB desde Next.js de varias maneras:
Integrate MongoDB with your Next.js application, then execute your MongoDB queries using the MongoDB Node Driver. For more information, see the blog post How to Integrate MongoDB Into Your Next.js App. Using MongoDB drivers is not compatible with App Services user-based Rules and Permissions.
Utiliza la API de datos de MongoDB para query MongoDB Atlas desde el servidor de Next.js. Para más información, consulta Data API Endpoints.