node-restful icon indicating copy to clipboard operation
node-restful copied to clipboard

Pagination info

Open Falci opened this issue 11 years ago • 10 comments

Would like an option to receive along with the data, or other request for pagination information at least the total records.

Thanks

Falci avatar Nov 04 '14 12:11 Falci

What other metadata would you like included? I see this best bundled as a separate module that does automaticaly adds an afterAll that wraps the response data with the calculated metadata

baugarten avatar Nov 11 '14 01:11 baugarten

Something like this: http://restcookbook.com/Resources/pagination/

Falci avatar Nov 11 '14 10:11 Falci

This is better accomplished using HTTP Headers, similar to the GitHub API -- https://developer.github.com/guides/traversing-with-pagination/

Do you have any metadata that you actually would like included in the response body?

baugarten avatar Nov 11 '14 16:11 baugarten

No, that's all. Thanks.

Falci avatar Nov 11 '14 16:11 Falci

Hi, I see it's been opened for two years now. Any update on this?

slavede avatar Aug 13 '16 20:08 slavede

I don't think this makes sense to bundle with node-restful because there are many ways to accomplish sending pagination info back to a client.

You could accomplish this by adding an after route to get and inspecting the parameters passed and then formatting the correct information by either wrapping the returned JSON or adding any number of HTTP headers to the response

baugarten avatar Aug 13 '16 21:08 baugarten

I see...so I've implemented after method. Here is the body of the function doing conversion if someone needs it:

// the ones not mentioned here will only get $ in front of it
const operatorMappings = {
    equals : '$eq'
};

exports.convertNodeRestful = function(query) {
    var mongooseQuery = {},
        splittedKey,
        operator;
    Object.keys(query).forEach(function(key) {
        if (nodeRestfulKeywords.indexOf(key) === -1) {
            splittedKey = key.split('__');
            if (splittedKey.length === 2) {
                operator = operatorMappings[splittedKey[1]] || '$' + splittedKey[1];
            } else {
                operator = '$eq';
            }

            mongooseQuery[splittedKey[0]] = {};
            mongooseQuery[splittedKey[0]][operator] = query[key];
        }
    });

    return mongooseQuery;
};

I guess that you can close this one if you don't think it's a valid request.

slavede avatar Aug 14 '16 11:08 slavede

Actually... I've thought about this a bit more (especially viewing your example). Maybe pagination info is something that could be extracted/provided more easily by the library.

Possibly not rendering it in the response but making it accessible or configurable for end users since this will almost always be needed. I'll leave this open

baugarten avatar Aug 16 '16 13:08 baugarten

Well, I've tried to implement it as before or after hook but no joy, headers already sent and stuff...

Resource.after('get', function(req, res, next) {
    if (!req.params.id) {
      next();
    }
    delete req.quer.options; // remove skip and limit to get total count
    req.quer.count(function(err, total) { // apply the query
      if (!err) {
        res.set('X-Total-Count', total);
      }
      next();
    });
  });

Now I need to try a hack in the library itself... shoulda support the X-Total-Count since 2015...

matheo avatar Mar 10 '17 03:03 matheo

The bellow code is working for me:

Resource.after('get', function(req, res, next) {
    delete req.quer.options;    // Remove skip and limit to get total count
    req.quer.countDocuments(function(err, totalRecords) { //Apply remaining query
          if (err) {
            console.log(err);
            next();
          }else {
            res.set('X-Total-Count', totalRecords);
            //console.log("Total records", totalRecords);
            next();
          }
     });
});

kefferavelino avatar Jun 25 '19 01:06 kefferavelino