5

I'm using express.js and sequelize.js to build an API. Once I retrieved an object from the DB using sequelize, I want to

  • filter out object attributes (e.g. retrieve the user, but don't render the User's password hash to the returned JSON)
  • add new object attributes

before I return it from the API as JSON.

Similar to what these Rails libraries do:

What's the most common framework to do that in node? Or do sequelize.js / express.js contain functionality to do that?

UPDATE

Ok, there is a basic example, passport.js gets the authenticated user's object from the DB and attaches it to req.user;

router.get('/me/data',
  passport.authenticate('bearer', { session: false }),
  function(req, res) {
    res.status(200).send(req.user);
  }
);

That would return the following JSON response:

{
  "id": 24,
  "first_name": "John",
  "last_name": "Doe",
  "email": "[email protected]",
  "password": "8d23cb9c4827bc06bb30ac47c06af0efbdbeb575001ab7de5387da4085f7184a381335c0f04b45f4a40e5a7042d47ae1e2d29d28fd5be1d534f09ba3db04e8ca",
  "updatedAt": "2016-01-25T09:19:07.422Z",
  "createdAt": "2016-01-25T09:19:07.422Z",
  "data": null
}

But I want to return something like this:

{
  "id": 24,
  "full_name": "John Doe",
  "email": "[email protected]",
  "data": null
}

And not just for this one case, but in any case a user object is rendered.

2
  • Could you show a example of what you get from your DB, and what you need your API to return? Commented Jan 25, 2016 at 7:57
  • @DrakaSAN Sure, here you go! Commented Jan 25, 2016 at 9:22

4 Answers 4

2

The simplest solution would be to edit req.user before sending it:

function

render (user) {
    callback({
        "id": user.id,
        "full_name": user.first_name + ' ' + user.last_name,
        "email": user.email,
        "data": null
    });
}

router.get('/me/data',
  passport.authenticate('bearer', { session: false }),
  function(req, res) {
    render(req.user, function(user) {
        res.status(200).send(user);
    });
  }
);
Sign up to request clarification or add additional context in comments.

2 Comments

Hmm, that's a possibility. What you call render would be an object representer for the user object. I might also want to have different object representers. My question is where do people conventionally put this kind of code? Inside a separate file? Into the model file? I mean someone MUST have thought of a common solution to that problem and how to structure your files then, right? :D
@kadrian I didn t put much thought in the naming tbh. It s probable someone thought of a norm, but I never saw or heard of it myself, but I m no specialist. I would put it close to the route handler (since it s only used there, and is directly linked to it)
2

This module will helper you with Grape Entity manner:

https://github.com/baijijs/entity

For example:

const Entity = require('baiji-entity');

const userEntity = new Entity({
  id: true,
  fullname: true,
  email: true,
  data: true
});

userEntity.parse(req.user);

// And the parsed result will be as below

{
  "id": 24,
  "full_name": "John Doe",
  "email": "[email protected]",
  "data": null
}

Hope this can help you.

Comments

0

Ok so you would like to chop of some of the fields? You could chop it of before the server is sending the response. For example with a module like this https://www.npmjs.com/package/json-chop or if you use mongo db you can hide the fields like described here https://docs.mongodb.org/manual/tutorial/project-fields-from-query-results/

1 Comment

I'm using Postgres. Chop looks interesting, but it doesn't seem like the "common" solution in the node.js world. Isn't there something most people use?
0

Without knowing more details about the setup, the following (untested) code has the potential to work. You could specify the attributes field in your query against the model in order to filter out results (based on certain conditions):

router.get('me/data',function(req, res) {
   db.UserModel.find({
     attributes:['id','first_name','last_name','email','data'],
     where: { id: req.user.id}, //put in here whatever you are using to get the info from the database
    })
    .then (function(user) {
        var formatUser = {
            id: user.id,
            full_name: user.first_name + ' ' + user.last_name,
            email: user.email,
            data: user.data,
        };
        res.json(formatUser);
    }
 });

See the following docs for more information:

http://docs.sequelizejs.com/en/latest/docs/models-usage/

http://docs.sequelizejs.com/en/latest/docs/querying/

2 Comments

Okay, that's sweet, but 1) I'd have to specify that on every find and 2) full_name is a dynamic attribute, how to compose that from first_name and last_name in this case?
For the finds, this is just making use of sequelize's API. You could abstract this out into a function, maybe call it findFilter, and only use it when needed. For the dynamic attribute, I edited the code to adjust the formatting. Another possibility is that you can change this on the back end, and return the result to the server as full_name

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.