Developing a Web Application with Netlify Serverless Functions and MongoDB
Rate this tutorial
As I mentioned in a , I'm a big fan of Netlify and the services they offer developers—my favorite of their services being their static website hosting and serverless functions. When combining the two, you can deploy a complex website or web application with a back end, without ever worrying about infrastructure or potentially complex API design.
So how does that work with a database like MongoDB?
If you've ever dabbled with serverless functions before, you might be aware that they are not always available for consumption. Many serverless functions exist for a defined amount of time and then are shut down until they are executed again. With this in mind, the connection to a database might not always be available like it would be in an application built with , for example. You could establish a connection every time a function is called, but then you risk too many connections, which might overload your database.
So what do you do?
There are a few things that must be ready to go prior to starting this tutorial.
- Node.js 15+ must be installed.
- You must have a Netlify account.
Everything we do in this tutorial can be done for free. You can use the free forever tier of MongoDB Atlas, which is an M0 sized cluster. You can also use the free plan that Netlify offers.
To keep this tutorial simple and easy to understand, we're going to work from a new project. While you don't necessarily need to use the CLI to get the job done, it will be easier for this example.
Assuming the Netlify CLI is installed, execute the following command to create a new project:
For this example, we won't be using the continuous integration features that you'd get when connecting GitHub and similar. Make sure to follow the instructions that the CLI presents you with from the above command.
We won't be creating any particular project files until we progress through the tutorial.
The star of this tutorial is going to be around properly including MongoDB Atlas in your Netlify Function. As previously mentioned, you have to take into consideration the state of the function to prevent attempting to access a database without a connection or establishing too many connections.
With that in mind, we can do the following with the Netlify CLI:
Since we'll be using the MongoDB Node.js driver, we need to install it into our project. From the command line, execute the following at the root of the project:
Netlify serverless functions will be able to access NPM modules at the root of the project.
So what is happening in the above code?
The first thing we're doing is creating a new MongoDB client using a URI string that we're storing within our environment variables. While you could hard code this URI, your best bet is to keep it in an environment variable because we'll be using them in a later step of this tutorial.
Probably the most interesting line here is the following:
If you've ever worked with the MongoDB Node.js driver before, you've probably used this with an
awaitor similar. We don't want to block our function in the global area. This area before the
handlerfunction will be executed only when the function starts up. We know that the function won't necessarily shut down after one execution. With this knowledge, we can use the same client for as long as this particular function exists, reducing how many connections exist.
handlerfunction, we can attempt to resolve our client promise, get a handle to the database we want to use, and get a handle to the collection we want to use. For this example, we are storing the database name and collection name in an environment variable.
For this particular function, we are using our connection to find all documents in our collection, limiting the result set to 10 documents, and returning the data to whatever executed the function. Our example is technically around movies documents, but our code doesn't really reflect anything that specific.
So we've got a serverless function for querying our MongoDB Atlas database. Let's tie it together with some of the other Netlify offerings, particularly the website hosting.
At the root of our Netlify project, create an index.html file with the following markup:
We don't need to worry about doing anything fancy from a UI perspective in this example.
Again, nothing fancy, but it proves that our function works.
We have a function, we have a website, and we're pretty much ready to deploy. Before we do that, let's make sure everything works locally.
Using the Netlify CLI, execute the following from the root of your project:
The above command should serve the function and site locally, and then open a browser for you. If you run into problems, you might check the following:
- Did you remember to set your environment variables first?
- Is your local IP address added to your MongoDB Atlas cluster?
To be honest, those two items got me, so I thought it was worth noting them.
Assuming you got everything working in your local environment, we can focus on the deployment to Netlify.
The first thing we'll want to do is create our environment variables. This can be done within the Netlify online dashboard or directly with the Netlify CLI. For this example, we'll use the CLI.
From the command line, execute the following:
The above command sets three environment variables. You'll want to swap the URI with that of your own cluster. You can get this information within the MongoDB Atlas dashboard.
The other two variables, which represent the database and collection, are using the sample dataset. You can change them to whatever you want.
With the variables in place, we can deploy the project. From the command line, execute the following command:
It might take a bit of time for the build process to kick in remotely, but when it's done, you should have a very basic website that consumes information from a Netlify Function.
It's worth noting that you still need to add proper network access rules to MongoDB Atlas to allow connections from a Netlify Function.
Remember, when working with serverless functions, you have to be aware that your functions may not always be available to reuse a connection. You also have to be aware that connecting to a database directly within a function handler might establish too many connections. When done properly, you'll have a powerful serverless function that can take full advantage of MongoDB.
ORLANDO, FLORIDA, US | IN-PERSON
Orlando Code Camp
Mar 25, 2023 | 12:00 PM - 9:00 PM UTC
Currency Analysis with Time Series Collections #2 — Simple Moving Average and Exponential Moving Average Calculation
May 16, 2022