Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to use the latest MongoDB best practices to limit connection pooling issues. #28350

Merged
merged 4 commits into from Aug 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 1 addition & 2 deletions examples/with-mongodb/.env.local.example
@@ -1,2 +1 @@
MONGODB_URI=
MONGODB_DB=
MONGODB_URI=
5 changes: 2 additions & 3 deletions examples/with-mongodb/README.md
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand All @@ -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.

Expand Down
63 changes: 23 additions & 40 deletions examples/with-mongodb/lib/mongodb.js
@@ -1,49 +1,32 @@
import { MongoClient } from 'mongodb'

const MONGODB_URI = process.env.MONGODB_URI
const MONGODB_DB = process.env.MONGODB_DB

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'
)
const uri = process.env.MONGODB_URI
const options = {
useUnifiedTopology: true,
useNewUrlParser: true,
}

/**
* 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
10 changes: 8 additions & 2 deletions 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 (
Expand Down Expand Up @@ -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()

Expand Down