Get Data from MongoDB with Netlify Functions Lambda

Learn how to query a database instance and return data without a backend server

Tue, 31 Jul 2018

This post will be rather short. We’re going to break down some code that will connect to a MongoDB instance, run a query and return the data to your application, all without a server :). Were going to need two packages in order to get this job done for us. The first is Co, which will allow us to write non blocking code and the second is mongoose, which is a tool that will allow us to work with our Mongo database in an asynchronous environment.

npm install mongoose or yarn add mongoose

npm install co or yarn add co

This is the entire code for the project, I’m going to share it now and break each part down piece by piece.

var co = require('co');
var mongoose = require('mongoose');

let conn = null;

const uri = 'mongodb://username:password@mongourl:port/databaseName';

exports.handler = function(event, context, callback) {

  context.callbackWaitsForEmptyEventLoop = false;

  run().
    then(res => {
      callback(null, res);
    }).
    catch(error => callback(error));
};

function run() {
  return co(function*() {

    if (conn == null) {
      conn = yield mongoose.createConnection(uri, {
        bufferCommands: false,
        bufferMaxEntries: 0
      });
      conn.model('collectionName', new mongoose.Schema({
        schedule: String,
        occupancy: Number,
        count: Number,
        price: Number,
        time: String,
        link: String
      }));
    }

    const M = conn.model('collectionName');

    const doc = yield M.find();
    const response = {
      statusCode: 200,
      body: JSON.stringify(doc)
    };
    return response;
  });
}

The first line of code we have is context.callbackWaitsForEmptyEventLoop = false; . You want to set this to false so you can reuse conn variable in between function calls. More info on this can be found at the following link.

The next block of code makes a call to our function that will query the database for us.

  run().
    then(res => {
      callback(null, res);
    }).
    catch(error => callback(error));

run() will call the function run, if it succeeded it will return the data from the function using the callback method. If the function call resulted in a failed response, it will call the callback function and return the error response it got.

This next part is where the magic happens. This block of code will check to see if it already has a connection to the database, if it does it will skip past this block and if it doesn’t, it will proceed to make a connection to our database.

    if (conn == null) {
      conn = yield mongoose.createConnection(uri, {
        bufferCommands: false,
        bufferMaxEntries: 0
      });
      conn.model('collectionName', new mongoose.Schema({
        schedule: String,
        occupancy: Number,
        count: Number,
        price: Number,
        time: String,
        link: String
      }));
    }

conn will attempt to make a connection to our database with the bufferCommands: false and bufferMaxEntries: 0 parameters. Setting both of these parameters will effectively disable buffering from happening. A default connection would queue up operations if it were to get disconnected from the MongoDB instance and then send them when it reconnects. Since we don’t have a server we want our calls to fail fast if there is no connection present. After we make our connection we will create a new schema for the collection we connected to. This portion is fairly straightforward, all you need to do is input your field and its data type.

The last portion will just use the collection that you connected to and finally query some data!

    const M = conn.model("collectionName");
    const doc = yield M.find();
    const response = {
      statusCode: 200,
      body: JSON.stringify(doc)
    };
    return response;

The first line of code will connect to our collection. After we connect we can start running queries. For the scheduler I wrote, I needed to return all the data in the collection. const doc = yield M.find(); does that for me while setting the return data to const named doc. Afterwards we create a new response to return our data. Your response needs to be an object that includes a body and statusCode key. Since the operation was successful, we use the status code 200 which means okay. We then stringify the doc object so we can send it in our response.

Wrapping up, there is nothing different that you would need to do to your front end. You can access this api function with a simple get call as follows:

    axios.get('/.netlify/functions/schedule')
    .then(res => {
      this.setState({schedule: res.data});
    })
Loading...
Edward Beazer

Edward Beazer - I just like to build shit. Sometimes I get stuck for hours, even days while trying to figure out how to solve an issue or implement a new feature. Hope my tips and tutorials can save you some time.