I want to preface by saying I have looked for this issue online and found solutions using mongoose, I do not use that so I don't know how well it translate here. Plus, I also using async/await instead of .then, so my code is different.
My question is that the API I have made in ExpressJS is super slow compared to the same API I have in Flask. I tried seeing why this is an issue, since JS is supposed to be faster than Python. I noticed it was due to me connecting to Mongo each time. I need to do this as my MongoDB has a different databases for different clients, so I cannot just have 1 constant connection to one database. Below is my Mongo code.
const {MongoClient} = require('mongodb');
const client = new MongoClient("mongodb+srv://abc@xyz.mongodb.net/<Cluster");
class MongoMethods {
constructor(company, collection){
this.company = company;
this.collection = collection;
}
async get(accessParameters){
try{
await client.connect();
const db = client.db(this.company);
const collection = db.collection(this.collection);
const val = await collection.findOne({"_id":accessParameters["at"]});
return val
} finally {
await client.close();
}
}
async putIn(putParameters, type){
try{
await client.connect();
const db = client.db(this.company);
const collection = db.collection(this.collection);
var existing = await collection.findOne({"_id":putParameters["at"]});
if(type === "array"){
var toAdd = existing !== undefined && putParameters["in"] in existing? existing[putParameters["in"]] : [];
toAdd.push(putParameters["value"]);
}else if(type === "dict"){
var toAdd = existing !== undefined && putParameters["in"] in existing? existing[putParameters["in"]] : {};
toAdd[putParameters["key"]] = putParameters["value"];
}else{
var toAdd = putParameters["value"];
}
await collection.updateOne({"_id":putParameters["at"]}, {"$set": {[putParameters["in"]]: toAdd}}, {upsert: true});
} finally {
await client.close();
}
}
async remove(removeParameters){
try{
await client.connect();
const db = client.db(this.company);
const collection = db.collection(this.collection);
if(removeParameters["key"] !== undefined){
await collection.updateOne({"_id":removeParameters["at"]}, {"$unset": {[removeParameters["in"] + "." + removeParameters["key"]] : ""}})
}else if(removeParameters["in"] !== undefined){
await collection.updateOne({"_id":removeParameters["at"]}, {"$unset": {[removeParameters["in"]] : ""}})
}else{
await collection.deleteOne({"_id":removeParameters["at"]})
}
}finally{
await client.close();
}
}
}
module.exports.MongoMethods = MongoMethods;
Below is how functions in my ExpressJS file look (I cannot post this file so this is an excerpt):
var express = require('express');
var cors = require('cors')
const bodyParser = require('body-parser');
const { validate, ValidationError } = require('express-superstruct');
const { MongoMethods } = require('./mongo.js')
let app = express()
app.use(cors())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.route('/enp1/')
.get(validate({uid : "string", site : "string"}), function (req, res) {
var args = req.query
var mongoClient = new MongoMethods(args.site, "collection_1")
mongoClient.get({at : args.uid}).catch(console.dir).then(result => {
if(result == undefined){ // This may need to take into account an empty dict
res.status(404).json({"Database Error" : "UID does not exists or site is not a valid website"})
}
res.status(200).json(result)
})
})
app.route('/enp2/')
.put(validate({site : "string", uid : "string", time : "string"}), function (req, res) {
var args = req.body;
var mongoClient = new MongoMethods(args.site, "time")
mongoClient.putIn({at : args.uid, in : "time", value : parseInt(args.time)}, "int").catch(console.dir).then(result => {
res.status(200).end()
})
})
It seems like this code is connecting to Mongo each time as I have to initialize the MongoMethods object each time. Can I prevent it from trying to connect each time so that my API doesn't have slow speeds? When I compare speeds, JS endpoints without Mongo are 50% faster than their Python counterpart but when using Mongo endpoints, it is around 300ms slower.
Let me know if you need anymore clarification.
Thanks in advance!
Edit 1: I wanted to mention, the API runs on AWS API Gateway and AWS Lambda@Edge functions.