1

Trying to connect to my mongodb database in the latest version of Nextjs. Things have changed so much, so I don't longer know what to do.

There's an example of how to set up the connection here: https://github.com/vercel/next.js/tree/canary/examples/with-mongodb

They use this file:

//The mongodb.js file from the example
import { MongoClient } from 'mongodb'

const uri = process.env.MONGODB_URI
const options = {}

let client
let clientPromise

if (!process.env.MONGODB_URI) {
  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()
  }
  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

However, they forgot to add how to actually use it. I can't even begin to figure it out.

//pages/api/user.js

import client from '/lib/mongodb.js'

export default async function handler(req, res) {
  //How do I connect here?
}

And two bonus questions:

  • I used to do caching on my database connection. Is it not needed anymore?
  • What happened to the utils folder? It used to be special, in that it didn't send anything there to the client. Now everyone seem to use lib but I don't think there's anything special with it?
Yeats
  • 2,112
  • 3
  • 30
  • 46
  • [This question](https://stackoverflow.com/questions/72210690/mongodb-atlas-connections-to-clusters-exceeded-nextjs-nextauth/) have some examples, and since you are using Vercel too, there are bonus answers to the problems you didn't discover yet. – Alex Blex Jul 18 '22 at 13:49
  • @AlexBlex Thanks. Can't find a single clear answer to any of my questions though. – Yeats Jul 18 '22 at 14:50
  • @AlexBlex I'm reading through your comments and trying my best to understand. My head is spinning very fast from all this! I understand it's pointless to cache in a serverless environment. I still would very very much like to avoid creating a wholly separate backend for my API! What is a serverless Atlas subscription, or data-api? – Yeats Jul 18 '22 at 15:35
  • @AlexBlex OTOH I don't really understand why caching can't work. Sure, the function closes, but why can't the connection to the database remain..? It works on my live production on an older Nextjs version, which still uses serverless functions. – Yeats Jul 18 '22 at 15:40
  • Atlas is a managed mongodb hosting. DB-as-a-service. You can try free tier https://www.mongodb.com/atlas/database As any service it comes with limits. One of them is number of connections. On dedicated host you are limited by OS - 65k sockets. Connection cannot be cached because of Vercel architecture. The mongo driver opens a persistent connection that can be reused, but only within the same nodejs process. Once the process dies, the connection is lost. Examples how to use the connection is in the question itself. Well, with few mistakes, but you should get the idea. – Alex Blex Jul 18 '22 at 16:37
  • @AlexBlex Guess I have to have a separate REST server. – Yeats Jul 18 '22 at 17:07
  • It depends (c) =) The OP there had an issue because free atlas tier allows only 500 connections. If you use self-hosted server your limit is like x100 bigger, so not necessarily a problem. – Alex Blex Jul 18 '22 at 21:02
  • @AlexBlex Isn't it a problem opening up thousands of connections? – Yeats Jul 19 '22 at 03:48
  • Only if it is cause problems =) World is not ideal and at some point you need to compromise quality for the sake of feasibility. It's up to you how to balance it. Considering you have picked managed low-maintenance app hosting, I assume number of open connections is not a concern unless it affects functionality visible from business level, right? – Alex Blex Jul 19 '22 at 10:49
  • @AlexBlex I suppose so! I'm honestly a little disappointed with Nextjs/Vercel on this. The benefits of a serverless environment are intangible to me, but the drawbacks are very real. I tried the Data API on Atlas but it was 12-15 times slower than the driver by the way. Maybe it's faster on a real Cluster instead of the free one? – Yeats Jul 19 '22 at 13:47
  • Right tools in the right hands do miracles in the intended usecases. Vercel positions itself as a platform to host clientside apps: "enables frontend teams to do their best work." Essentially hosting of static content with **support** of dynamic content, API, databases, and many other things. Whilst it is focused to make Nextjs shine where it's best, the auxiliary technologies are not the most efficient. They may improve in the future, may even take over the frontend component. After all AWS started as a bookstore. – Alex Blex Jul 19 '22 at 16:33
  • @Yeats GH knows the difference between "Mine" and "mine". Your OS may not, e.g., some OSes are case-preserving-but-insensitive. – Dave Newton Jan 12 '23 at 17:22

1 Answers1

2

You can do like this:

const dbClient = await client;
const db = dbClient.db('db-name');
const collection = db.collection('collection-name');
// example to get a doc in collection
const doc = await collection.findOne({query:""}, {...options})
Shiva
  • 476
  • 3
  • 15