How To Send Secure API Responses with MongoDB

·

2 min read

MongoDB is special among other databases in that it uses _id instead of id. Let's suppose we are in a scenario where we have a microservices application and one service uses MySQL database and another service uses MongoDB database. Getting JSON responses from both of them will be inconsistent because they both store the IDs differently, and that will make consuming the API unexpected.

Let's see together how we can solve this problem and modify the response of MongoDB to return id instead of _id in a centralized location in our codebase.

Transforming _id to id not only will make the responses consistent, but also secure because it doesn't tell the client what database we are using in the backend which prevents any exploitation of known MongoDB vulnerabilities.

Modern APIs return JSON objects as responses. So as a quick reminder on how JavaScript turns object literals into JSON objects:

💡
Reminder: every object we create in JavaScript has a default property called toJSON() and it gets invoked every time we call JSON.stringify().

So to modify the returned JSON, we simply have to modify the toJSON() method attached to that object. Let's see that by pasting this code in your console:

const obj = { name: 'mark', toJSON() { return 2 } }
JSON.stringify(obj)

Similar logic is applied inside mongoose. In a Mongoose schema, we can define a property called toJSON() that works similarly to JavaScript version. Let's see it in action:

const userSchema = new mongoose.Schema(
  {
    email: String,
    password: String,
  },
  {
    toJSON: {
      transform(doc, ret) {
        ret.id = ret._id;
        delete ret._id;
        delete ret.password;
      },
      versionKey: false,
    },
  }
);

In Mongoose, the toJSON is a property that accepts a method called transform() that is responsible to transform the document before returning it. To do that, all we have to do is to modify the returned object ret in place. From the code above, you see I removed the password property and defined a new id property.

That's it! It's that easy to make our API responses consistent and secure.