Getting Started With Google Cloud Functions and MongoDB

Share this article

Getting Started With Google Cloud Functions and MongoDB

This article was originally published on Code Barbarian. Thank you for supporting the partners who make SitePoint possible.

Serverless architectures are becoming increasingly popular, and with good reason. In my experience, container-based orchestration frameworks have a steep learning curve and are overkill for most consumer-facing companies. With FaaS architectures, like AWS Lambda and Azure Functions, in theory the only devops you need is bundling and uploading your app.

This article will walk you through setting up a Google Cloud Function in Node.js that connects to MongoDB. However, one major limitation of stateless functions is the need to establish a separate database connection every time the stateless function runs, which incurs a major performance penalty. Unfortunately, I haven’t been able to figure out how to reuse a database connection in Google Cloud Functions, the trick that works for IBM Cloud, Azure Functions, and AWS Lambda does not work for Google Cloud Functions.

“Hello, World” in Google Cloud Functions

Go to the Google Cloud Functions landing page and click “Try it free”.

Click on the hamburger icon in the upper left and find the “Cloud Functions” link in the sidebar, then click “Create function”.

Name your function “hello-world” and leave the rest of the options in the “Create function” form unchanged. Leave “Function to execute” as “helloWorld”, because that needs to match the name of the function your code exports. Below is the code you should enter in, so you can confirm what version of Node.js your function is running on.

exports.helloWorld = (req, res) => {
  res.send('Hello from Node.js ' + process.version);
};

Click “Create” and wait for Google to deploy your cloud function. Once your function is deployed, click on it to display the function’s details.

Click the “Trigger” tab to find your cloud function’s URL.

Copy the URL and use curl to run your cloud function.

$ curl https://us-central1-test21-201718.cloudfunctions.net/hello-world
Hello from Node.js v6.11.5
$

Google Cloud Functions don’t give you any control over what version of Node.js you run, they run Node.js v6.11.5 currently. You can’t use async/await natively on Google Cloud Functions at the time of this writing.

Connecting to MongoDB Atlas

Click on the “Source” tab in the function details and hit the “Edit” button. You’ll notice there’s 2 files in your source code, one of which is package.json. Edit package.json to match the below code.

{
  "name": "sample-http",
  "version": "0.0.1",
  "dependencies": {
    "co": "4.6.0",
    "mongodb": "3.x"
  }
}

Once you redeploy, Google Cloud will automatically install your npm dependencies for you. Now, change your index.js to match the below code, replacing the uri with your MongoDB Atlas URI.

const co = require('co');
const mongodb = require('mongodb');

const uri = 'ATLAS_URI_HERE';

exports.helloWorld = (req, res) => {
  co(function*() {
    const client = yield mongodb.MongoClient.connect(uri);

    const docs = yield client.db('test').collection('tests').find().toArray();
    res.send('Result: ' + JSON.stringify(docs));
  }).catch(error => {
    res.send('Error: ' + error.toString());
  });
};

Click “Save” to deploy your function. Once it is deployed, you should be able to curl your cloud function and get a document from MongoDB Atlas back.

$ curl https://us-central1-test21-201718.cloudfunctions.net/hello-world
Result: [{"_id":"5a7b7df69d07887542605888","name":"Hello!","__v":0}]
$

At this point, you would try re-using the database connection using the same global state trick that works in AWS Lambda and other cloud function providers.

const co = require('co');
const mongodb = require('mongodb');

const uri = 'ATLAS_URI_HERE';

// Other cloud providers would retain this, but not Google Cloud
let client = null;

exports.helloWorld = (req, res) => {
  co(function*() {
    const reusedConnection = client != null;
    if (client == null) {
      client = yield mongodb.MongoClient.connect(uri);   
    }

    const docs = yield client.db('test').collection('tests').find().toArray();
    res.send('Result: ' + JSON.stringify(docs) + ', Reused: ' + reusedConnection);
  }).catch(error => {
    res.send('Error: ' + error.toString());
  })
};

Unfortunately, the global state trick doesn’t seem to work in Google Cloud.

$ curl https://us-central1-test21-201718.cloudfunctions.net/hello-world
Result: [{"_id":"5a7b7df69d07887542605888","name":"Hello!","__v":0}], Reused: false
$
$ curl https://us-central1-test21-201718.cloudfunctions.net/hello-world
Result: [{"_id":"5a7b7df69d07887542605888","name":"Hello!","__v":0}], Reused: false
$

Moving On

FaaS is a powerful paradigm, but purely stateless functions suffer from performance limitations when dealing with databases because establishing a new database connection is costly. Most cloud function providers have a mechanism for retaining database connections between function calls, but apparently Google Cloud Functions does not. This severely limits Google Cloud Functions’ ability to serve as a replacement for a conventional web server.

Frequently Asked Questions (FAQs) about Google Cloud Functions and MongoDB

How do I connect MongoDB to Google Cloud Functions?

Connecting MongoDB to Google Cloud Functions involves a few steps. First, you need to install the MongoDB client for Node.js using npm install mongodb. Then, in your Google Cloud Function, you can use the MongoClient.connect() function to connect to your MongoDB instance. You’ll need to provide the connection string for your MongoDB instance, which you can get from the MongoDB Atlas dashboard. Once connected, you can use the db.collection() function to interact with your MongoDB collections.

How do I deploy a Google Cloud Function that uses MongoDB?

To deploy a Google Cloud Function that uses MongoDB, you first need to write your function in a supported language like Node.js or Python. Your function should include code to connect to MongoDB and perform the desired operations. Once your function is written, you can deploy it using the gcloud functions deploy command. You’ll need to specify the name of your function, the runtime, the trigger, and the path to your function code.

How do I handle errors when connecting to MongoDB from a Google Cloud Function?

Error handling is crucial when connecting to MongoDB from a Google Cloud Function. You can use try/catch blocks to catch any errors that occur when connecting to MongoDB or performing operations. In the catch block, you can log the error message to the console or send it to an error tracking service. This will help you diagnose and fix any issues that occur.

Can I use Google Cloud Functions with MongoDB Atlas?

Yes, you can use Google Cloud Functions with MongoDB Atlas. MongoDB Atlas is a fully managed MongoDB service that provides a straightforward way to set up, secure, and scale MongoDB in the cloud. You can connect to your MongoDB Atlas cluster from a Google Cloud Function using the MongoDB connection string provided in the MongoDB Atlas dashboard.

How do I secure my MongoDB connection in a Google Cloud Function?

Securing your MongoDB connection in a Google Cloud Function is crucial to protect your data. You should never hardcode your MongoDB connection string in your function code. Instead, use environment variables to store your connection string. You can set environment variables in the Google Cloud Console or using the gcloud functions deploy command. This way, your connection string is not exposed in your code and is securely stored in the Google Cloud environment.

How do I use the MongoDB Node.js driver in a Google Cloud Function?

To use the MongoDB Node.js driver in a Google Cloud Function, you first need to install it using npm install mongodb. Then, you can require it in your function code using const MongoClient = require(‘mongodb’).MongoClient. You can then use the MongoClient.connect() function to connect to MongoDB and the db.collection() function to interact with your MongoDB collections.

How do I test a Google Cloud Function that uses MongoDB?

Testing a Google Cloud Function that uses MongoDB can be done locally using tools like the Functions Framework for Node.js. You can write tests using a testing library like Mocha or Jest and use a tool like Sinon.js for stubbing and mocking. You can also use an in-memory MongoDB server like mongodb-memory-server for testing MongoDB operations.

How do I monitor a Google Cloud Function that uses MongoDB?

Google Cloud provides several tools for monitoring Cloud Functions, including Cloud Logging and Cloud Monitoring. You can use these tools to monitor function invocations, execution times, and errors. You can also log custom metrics, like the number of documents inserted into MongoDB, using the @google-cloud/monitoring library.

How do I optimize the performance of a Google Cloud Function that uses MongoDB?

Optimizing the performance of a Google Cloud Function that uses MongoDB involves several strategies. One strategy is to use connection pooling to reuse MongoDB connections across function invocations. Another strategy is to use indexes in MongoDB to speed up query performance. You should also follow best practices for writing efficient Cloud Functions, like minimizing the use of global variables and avoiding long-running functions.

How do I handle MongoDB connection failures in a Google Cloud Function?

Handling MongoDB connection failures in a Google Cloud Function involves using error handling and retry logic. You can use a try/catch block to catch connection errors and log them for debugging. You can also use the autoReconnect option in the MongoClient.connect() function to automatically retry connections. If a connection failure occurs, you should return an error response from your function and handle it appropriately in your application.

Valeri KarpovValeri Karpov
View Author
joelfmongodbsponsored
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week