Search code examples
node.jsmongodbvercel

504 Gateway timeout when trying to access a MongoDB collection from a Vercel deployment


I have a basic NodeJS project with this structure:

/configs
  db.config.js
/routes
  testRoutes.js
index.js
vercel.json

Where the index.js where the server is looks like this:

const express = require('express');
const connectToDb = require('./configs/db.config');
const cors = require('cors');
const path = require('path');
const testRouter = require('./routes/testRoutes');
const app = express();
const PORT = process.env.PORT || 5000;

app.use(cors());
app.use(express.json());
app.use('/', express.static(path.join(__dirname, '/public')));

app.use('/test', testRouter.getUsers);

connectToDb()
  .then((res) => {
    app.listen(PORT, () => {
      console.log(`Server is running on port: ${PORT}`);
    });
  })
  .catch((err) => {
    console.log(err);
  });

module.exports = app;

db.config.js connects to the db once and gets exported to be used whenever there is need:

const {MongoClient} = require('mongodb');
const uri = `mongodb+srv://${process.env.DB_USER}:` +
            `${process.env.DB_PASSWORD}@${process.env.DB_CLUSTER_URL}/` +
            `?retryWrites=true&w=majority&appName=${process.env.DB_APP_NAME}`;
const client = new MongoClient(uri);

let database;

const connectToDb = async () => {
  if (database) {
    return database;
  }
  try {
    await client.connect();
    console.log('Connected to MongoDB');
    database = client.db(process.env.DB_NAME);
    return database;
  } catch (error) {
    console.log(error);
  }
};

module.exports = connectToDb;

Aside from this, in the server I have a /test route which when accessed calls a function to retrieve all records from a mongo db collection called users:

const connectToDb = require('../configs/db.config');

const getUsers = async (req, res) => {
  try {
    let db = await connectToDb();
    const collection = db.collection(process.env.DB_COLLECTION);
    const data = await collection.find({}).toArray();
    res.send(data);
  } catch (error) {
    console.error('Error accessing the database', error);
    res.status(500).send('Failed to fetch data');
  }
};

module.exports = {
  getUsers,
};

When I run this locally, after going to http:localhost:5000/test the db record (since right now there's only one) shows in the window, but if I deploy this to a Vercel project when I go to /test I get a gateway timeout: enter image description here

I'm rather new to using Vercel, but from the logs I don't seem to be getting much info: enter image description here Has anyone come across this issue? If it helps, the vercel.json config is this:

{
  "version": 2,
  "builds": [{
      "src": "index.js",
      "use": "@vercel/node"
  }],
  "routes": [{
      "src": "/(.*)",
      "dest": "index.js"
  }]
}

I'm not that knowleageable in MongoDB either, so I'm not sure if this could be an access issue even though it's a 504 error, but maybe I'm missing some configuration to allow the setup for my deployed Vercel instance? Please let me know if you have any idea what could be wrong.


Solution

  • After searching a bit, I found that the error I've been getting is because there needs to be a MongoDB integration with Vercel, namely by following this link: https://vercel.com/integrations/mongodbatlas and following the steps by selecting my Backend project, the MongoDB database I had created, and that allows for a connection. Though at first it failed, it was because after some refactoring I had changed the password of the user I had assigned the integration. Changing this variable accordingly in the Vercel app's environment variables did the trick