Node JS Mongo Client for Atlas Data API

Without using axios or any third party library.

MongoDB Atlas provides a set of API endpoints that can be used to access the database hosted on Atlas without the need for database drivers; great for minimal memory footprint, especially on serverless infrastructures such as AWS Lambda.

Instead of bare-bone API calls directly, we can create a helper client and wrap the logic we want in methods. We won’t use axios or any third-party package but use the native https module.

The Code

import * as https from "https";

const defaultOptions = {
  protocol: 'https:',
  hostname: process.env.MONGO_HOST_NAME,
  port: 443,
  method: 'POST',
  path: process.env.MONGO_PATH,
  headers: {
    'Content-Type': 'application/json',
    "Access-Control-Request-Headers": "*",
    'api-key': process.env.MONGO_DATA_API_KEY,
  }
};

const postBody = {
  "database": process.env.MONGO_DATABASE,
  "dataSource": process.env.MONGO_DATASOURCE
};

const post = ({ collection, action, data, update, filter, projection }) => {
  const options = {
    ...defaultOptions,
    path: defaultOptions.path + action
  };

  return new Promise((resolve, reject) => {
    const req = https
      .request(options, (res) => {
        res.setEncoding("utf8");
        let body = "";
        res.on("data", (chunk) => (body += chunk));
        res.on("end", () => {
          resolve(JSON.parse(body))
        });
      })
      .on("error", reject);
    req.write(JSON.stringify({
      ...postBody,
      collection,
      filter: filter ?? undefined,
      document: data ?? undefined,
      projection: projection ?? undefined,
      update: update ?? undefined
    }));
    req.end();
  });
};

const findOne = async ({ collection, filter, projection }) => {
  try {
    const result = await post({ collection, action: "findOne", filter, projection });
    if (!result || result.document === undefined) {
      console.log(result);
      throw new Error();
    }
    return result.document;
  } catch (e) {
    console.log(e);
    throw new Error();
  }
}

const findMany = async ({ collection, filter, projection }) => {
  try {
    const result = await post({ collection, action: "find", filter, projection });
    if (!result.documents) {  
      console.log(result);    
      throw new Error();
    }
    return result.documents;
  } catch (e) {
    console.log(e);
    throw new Error();
  }
}

const insertOne = async ({ collection, data }) => {
  try {
    const result = await post({ collection, action: "insertOne", data });
    if (!result.insertedId) {   
      console.log(result);   
      throw new Error();
    }
    return result.insertedId;
  } catch (e) {
    console.log(e);
    throw new Error();
  }
}

const updateOne = async ({ collection, filter, data, pushData }) => {
  try {
    const update = {
      "$set": data,
      "$push": pushData ?? undefined
    }
    const result = await post({ collection, action: "updateOne", filter, update });
    if (result.matchedCount === undefined) {
      console.log(result);
      throw new Error();
    }
    return result;
  } catch (e) {
    console.log(e);
    throw new Error();
  }
}

export { findOne, findMany, insertOne, updateOne };

In all these methods, you must pass collection as required and other relevant data to perform different operations on your database.

For these APIs to work, you must set up an API key from Atlas dashboard and provide it in the env variable process.env.MONGO_DATA_API_KEY.

You can add type safety to this code with TypeScript.




See also

When you purchase through links on techighness.com, I may earn an affiliate commission.