node.js - Is it considered bad practice to manipulate a queried database document before sending to the client in Mongoose? -


so spent long trying figure out how manipulate returned database document (using mongoose) using transform , virtuals, purposes, aren't options. behaviour desire similar of transform (in delete property), want delete property returned document iff satisfies requirement calculated using req.session.user/req.user object (i'm using passportjs, equivalent session user suffices). obviously, there no access request object in virtual or transform, , can't calculation.

then dawned on me query , manipulate returned object in callback before send client. , put in middleware function looks nice, tells me hacky thing do. i'm presenting api client not reflect data stored/retrieved directly database. may clutter route configuration if have middleware on making harder maintain code. below example of manipulation looks like:

app.route('/api/items/:id').get(manipulateitem, senditem); app.param('id', finduniqueitem);  function finduniqueitem(req, res, next, id) {     item.finduniquebyid(id, function(err, item) {         if (!err) { req.itemfound = item; }         next();     } }  function manipulateitem(req, res, next) {     if (req.itemfound.people.indexof(req.user) === -1) {         req.itemfound.userisinpeoplearray = false;     } else {         req.itemfound.userisinpeoplearray = true;     }     delete req.itemfound.people; }  function senditem(req, res, next) {     res.json(req.itemfound); } 

i feel workaround problem simpler solution, i'm not sure solution is.

there's nothing hacky act of modifying it.
it's matter of when modify it.

for toy servers, , learning projects, answer whenever want.
in production environments, want transform on way out of system, , next system (the next system might end user; might server; might big block of functionality in own server, shouldn't have access more information needs job).

getitemsfromsomewhere()   .then(transformtotypeicanuse)   .then(filterbasedonmyexpectations)   .then(dooperations)   .then(transformtotypeipromisedyou)   .then(outputtonextsystem); 

that example might not super-helpful in terms of actual how, that's sort of point.
can see, link system of events system of events (that own transform own data-structure, own filtering/mapping, transforms data whatever api promises, , passes along next system, , out end user).

i think part of sense of "hacking" comes bolting result of async process onto req, req gets injected step step, through middleware.

that said:

function eq (a) {   return function (b) { return === b; }; }  function makeoutputobject (inputobject, personwasfound) {   // return whatever want }  var personfound = req.itemfound.people.some(eq(req.user)); var outputobject = makeoutputobject(req.itemfound, personfound); 

now aren't using actual delete keyword, or modifying call-to-call state of itemfound object.

you're separating view-based logic app-based logic, without formal barriers (can added later, if they're needed).


Comments