From c4c5541c16de6ffabdbc81e27f9625508e79951c Mon Sep 17 00:00:00 2001 From: Ado Kukic Date: Fri, 20 Aug 2021 11:05:55 -0700 Subject: [PATCH 1/2] Update to use the latest MongoDB best practices. --- examples/with-mongodb/.env.local.example | 3 +- examples/with-mongodb/README.md | 5 +- examples/with-mongodb/lib/mongodb.js | 67 +++++++++--------------- examples/with-mongodb/pages/index.js | 10 +++- 4 files changed, 36 insertions(+), 49 deletions(-) diff --git a/examples/with-mongodb/.env.local.example b/examples/with-mongodb/.env.local.example index 0bc8a2ce22f98..9dead415dc211 100644 --- a/examples/with-mongodb/.env.local.example +++ b/examples/with-mongodb/.env.local.example @@ -1,2 +1 @@ -MONGODB_URI= -MONGODB_DB= \ No newline at end of file +MONGODB_URI= \ No newline at end of file diff --git a/examples/with-mongodb/README.md b/examples/with-mongodb/README.md index 77add3af3cb0e..12db73e8f41fd 100644 --- a/examples/with-mongodb/README.md +++ b/examples/with-mongodb/README.md @@ -11,7 +11,7 @@ If you want to learn more about MongoDB, visit the following pages: Once you have access to the environment variables you'll need, deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example): -[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-mongodb&project-name=with-mongodb&repository-name=with-mongodb&env=MONGODB_URI,MONGODB_DB&envDescription=Required%20to%20connect%20the%20app%20with%20MongoDB) +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-mongodb&project-name=with-mongodb&repository-name=with-mongodb&env=MONGODB_URI&envDescription=Required%20to%20connect%20the%20app%20with%20MongoDB) ## How to use @@ -40,7 +40,6 @@ cp .env.local.example .env.local Set each variable on `.env.local`: - `MONGODB_URI` - Your MongoDB connection string. If you are using [MongoDB Atlas](https://mongodb.com/atlas) you can find this by clicking the "Connect" button for your cluster. -- `MONGODB_DB` - The name of the MongoDB database you want to use. ### Run Next.js in development mode @@ -56,7 +55,7 @@ yarn dev Your app should be up and running on [http://localhost:3000](http://localhost:3000)! If it doesn't work, post on [GitHub discussions](https://github.com/vercel/next.js/discussions). -You will either see a message stating "You are connected to MongoDB" or "You are NOT connected to MongoDB". Ensure that you have provided the correct `MONGODB_URI` and `MONGODB_DB` environment variables. +You will either see a message stating "You are connected to MongoDB" or "You are NOT connected to MongoDB". Ensure that you have provided the correct `MONGODB_URI` environment variable. When you are successfully connected, you can refer to the [MongoDB Node.js Driver docs](https://mongodb.github.io/node-mongodb-native/3.4/tutorials/collections/) for further instructions on how to query your database. diff --git a/examples/with-mongodb/lib/mongodb.js b/examples/with-mongodb/lib/mongodb.js index 12db0928f904d..65e84c19791f4 100644 --- a/examples/with-mongodb/lib/mongodb.js +++ b/examples/with-mongodb/lib/mongodb.js @@ -1,49 +1,32 @@ -import { MongoClient } from 'mongodb' +import { MongoClient } from 'mongodb'; -const MONGODB_URI = process.env.MONGODB_URI -const MONGODB_DB = process.env.MONGODB_DB +const uri = process.env.MONGODB_URI; +const options = { + useUnifiedTopology: true, + useNewUrlParser: true, +}; -if (!MONGODB_URI) { - throw new Error( - 'Please define the MONGODB_URI environment variable inside .env.local' - ) -} - -if (!MONGODB_DB) { - throw new Error( - 'Please define the MONGODB_DB environment variable inside .env.local' - ) -} - -/** - * Global is used here to maintain a cached connection across hot reloads - * in development. This prevents connections growing exponentially - * during API Route usage. - */ -let cached = global.mongo +let client; +let clientPromise; -if (!cached) { - cached = global.mongo = { conn: null, promise: null } +if (!process.env.MONGODB_URI) { + throw new Error('Please add your Mongo URI to .env.local'); } -export async function connectToDatabase() { - if (cached.conn) { - return cached.conn +if (process.env.NODE_ENV === 'development') { + // In development mode, use a global variable so that the value + // is preserved across module reloads caused by HMR (Hot Module Replacement). + if (!global._mongoClientPromise) { + client = new MongoClient(uri, options); + global._mongoClientPromise = client.connect(); } - - if (!cached.promise) { - const opts = { - useNewUrlParser: true, - useUnifiedTopology: true, - } - - cached.promise = MongoClient.connect(MONGODB_URI, opts).then((client) => { - return { - client, - db: client.db(MONGODB_DB), - } - }) - } - cached.conn = await cached.promise - return cached.conn + clientPromise = global._mongoClientPromise; +} else { + // In production mode, it's best to not use a global variable. + client = new MongoClient(uri, options); + clientPromise = client.connect(); } + +// Export a module-scoped MongoClient promise. By doing this in a +// separate module, the client can be shared across functions. +export default clientPromise; \ No newline at end of file diff --git a/examples/with-mongodb/pages/index.js b/examples/with-mongodb/pages/index.js index 17e3b78f7d735..4882eb0006529 100644 --- a/examples/with-mongodb/pages/index.js +++ b/examples/with-mongodb/pages/index.js @@ -1,5 +1,5 @@ import Head from 'next/head' -import { connectToDatabase } from '../lib/mongodb' +import clientPromise from '../lib/mongodb' export default function Home({ isConnected }) { return ( @@ -223,7 +223,13 @@ export default function Home({ isConnected }) { } export async function getServerSideProps(context) { - const { client } = await connectToDatabase() + const client = await clientPromise + + // client.db() will be the default database passed in the MONGODB_URI + // You can change the database by calling the client.db() function and specifying a database like: + // const db = client.db("myDatabase"); + // Then you can execute queries against your database like so: + // db.find({}) or any of the MongoDB Node Driver commands const isConnected = await client.isConnected() From 0e4263d32f5e04790506251d98e56f98120bc4ef Mon Sep 17 00:00:00 2001 From: "jj@jjsweb.site" Date: Wed, 25 Aug 2021 12:45:09 -0500 Subject: [PATCH 2/2] lint-fix --- examples/with-mongodb/lib/mongodb.js | 24 ++++++++++++------------ examples/with-mongodb/pages/index.js | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/examples/with-mongodb/lib/mongodb.js b/examples/with-mongodb/lib/mongodb.js index 65e84c19791f4..2990cffd2cac4 100644 --- a/examples/with-mongodb/lib/mongodb.js +++ b/examples/with-mongodb/lib/mongodb.js @@ -1,32 +1,32 @@ -import { MongoClient } from 'mongodb'; +import { MongoClient } from 'mongodb' -const uri = process.env.MONGODB_URI; +const uri = process.env.MONGODB_URI const options = { useUnifiedTopology: true, useNewUrlParser: true, -}; +} -let client; -let clientPromise; +let client +let clientPromise if (!process.env.MONGODB_URI) { - throw new Error('Please add your Mongo URI to .env.local'); + throw new Error('Please add your Mongo URI to .env.local') } if (process.env.NODE_ENV === 'development') { // In development mode, use a global variable so that the value // is preserved across module reloads caused by HMR (Hot Module Replacement). if (!global._mongoClientPromise) { - client = new MongoClient(uri, options); - global._mongoClientPromise = client.connect(); + client = new MongoClient(uri, options) + global._mongoClientPromise = client.connect() } - clientPromise = global._mongoClientPromise; + clientPromise = global._mongoClientPromise } else { // In production mode, it's best to not use a global variable. - client = new MongoClient(uri, options); - clientPromise = client.connect(); + client = new MongoClient(uri, options) + clientPromise = client.connect() } // Export a module-scoped MongoClient promise. By doing this in a // separate module, the client can be shared across functions. -export default clientPromise; \ No newline at end of file +export default clientPromise diff --git a/examples/with-mongodb/pages/index.js b/examples/with-mongodb/pages/index.js index 4882eb0006529..9628afb6523c7 100644 --- a/examples/with-mongodb/pages/index.js +++ b/examples/with-mongodb/pages/index.js @@ -226,7 +226,7 @@ export async function getServerSideProps(context) { const client = await clientPromise // client.db() will be the default database passed in the MONGODB_URI - // You can change the database by calling the client.db() function and specifying a database like: + // You can change the database by calling the client.db() function and specifying a database like: // const db = client.db("myDatabase"); // Then you can execute queries against your database like so: // db.find({}) or any of the MongoDB Node Driver commands