Search code examples
node.jsmongodbrestmongooseapi-design

Structuring Node API (express, mongodb, mongoose) For Conditionally Returned Values Based On User Type


I'm building a REST API using Node with express, mongodb, and mongoose.

What I'm trying to accomplish is this. An endpoint that returns object values conditionally based off of the users role (available in the request, like USER or ADMIN).

As a standard user (USER), your response may look like this {id: "123", email: "[email protected]"}

Whereas the response for an admin (ADMIN) would look like {id: "123", email: "[email protected]", password: "abc"}

Also, what is the best way to protect values on patch requests so that some keys can only be updated by users of a specific role. Is there a good solution to do this with mongoose (preferably using mongoose schema, to reduce redundancy)? If not, what would be the best way to incorporate a json validation library?

I've found plenty of documentation online for building REST APIs with this stack, but I was unable to find any that address my questions.


Solution

  • I think mongoose doesn't provide this feature out of the box. I believe you have to do it manually. Although, you can make use of module like schema-utils to do validation.

    If I were you I would do something like this:

    • Use some kind of authentication method.
    • Create a property named role in mongoose User schema. Where role can be admin/user etc.
    • Create a middleware to check if the current user is admin. Ex: app.post('/', auth.isAdmin, (req, res) => {}). Here isAdmin middleware check if the role is admin then proceed to next middleware.
    • I would also populate req.user object with the current logged in user's data.

    So, my code would be something like this:

    app.patch('/email', auth.isAdmin, (req, res) => { DO UPDATE HERE });
    

    Another example:

    app.get('/user/:id', auth.isAuthenticated, (req, res) => {
      if (req.user.role === 'admin') { DO STUFF }
      eles { DO STUFF }
    })
    

    Not sure if this would help you in any way.