Hi guys,
I'm using aws-serverless-express repository for a project, and I'm trying to optimize Mongodb connection when Lambda function is awakened.
Currently, for each call, my function create a new Mongodb connection (too bad...), and I found this solution: keep in global variable, the Mongodb connection.

(Full article: https://blog.cloudboost.io/i-wish-i-knew-how-to-use-mongodb-connection-in-aws-lambda-f91cd2694ae5)
But I don't know how to do that with my current architecture code:
"use strict";
const awsServerlessExpress = require("aws-serverless-express");
const app = require("./app");
const binaryMimeTypes = [
"application/javascript",
"..."
];
const server = awsServerlessExpress.createServer(app, null, binaryMimeTypes);
exports.handler = (event, context) => awsServerlessExpress.proxy(server, event, context);
Currently my Mongodb connection is done in app.js file. So each call reload app.js file...
I'm looking for a solution to send my Mongodb variable to my file app and keep alive Mongodb connection while Lambda function is awakened.
Thanks for your help.
You should be fine. app.js will only be loaded once per Lambda container (or "cold start")
I have similar requirement. Then how do you pass the global variable dbConnection to app.js?
// Following code is in index.js which is used for Lambda
"use strict";
const dbConnection = MongoClient.connect('...');
const awsServerlessExpress = require("aws-serverless-express");
const app = require("./app"); // app.js is used to create application.
const binaryMimeTypes = [
"application/javascript",
"..."
];
const server = awsServerlessExpress.createServer(app, null, binaryMimeTypes);
exports.handler = (event, context) => awsServerlessExpress.proxy(server, event, context);
// how to pass dbConnection to app.js? or just use it in app.js?
// how to pass dbConnection to app.js? or just use it in app.js?
Don't. Instantiate the dbConnection in the app.js module.
I used lodash-memoize to cache the function. This solved my problem. Here is my code example, if someone is interested.
// index.js
const containerId = Date.now().toString().slice(-6);
exports.handler = async (event) => {
const generate = require('./generator.js');
console.log(`ContainerId: ${containerId}`);
generate('clientId1');
generate('clientId2');
generate('clientId1');
generate('clientId2');
};
// generate.js
const memoize = require('./memoize');
const getClientSecret = (clientId) => {
console.log('hello');
return clientId;
};
const cachedSecret = memoize(getClientSecret);
const generate = (clientId) => {
const cs = cachedSecret(clientId);
console.log(cs);
return cs;
};
module.exports = generate ;
//memoize.js is lodash-memoize source code. I just use the source code here.
The result looks like this:
// First trigger lambda
ContainerId: 071040
hello
clientId1
hello
clientId2
clientId1
clientId2
// Second time to trigger lambda
ContainerId: 071040
clientId1
clientId2
clientId1
clientId2
What I found:
getClientSecret function.I'm sharing my MongoDB client with app.locals in app.js like this:
app.js:
new MongoClient.connect(config.mongo.url, config.mongo.options).then((client) => {
logger.info('Connected to MongoDB')
app.locals.client = client
})
// routes
app.use('/', routes)
In a route i do:
router.route('/foo').get(async (req, res) => {
const { client } = req.app.locals
... some db logic
})
In my localhost this works, but when i deploy to the lamdba, the client becomes undefined, how should i share the mongo client between routes?
I've written here how we are doing it for both https://confy.app and https://angoralabs.com.
Most helpful comment
I used lodash-memoize to cache the function. This solved my problem. Here is my code example, if someone is interested.
The result looks like this:
What I found:
getClientSecretfunction.