How should I send a GET request to a koa backend that will return conditional results?

3.4k views Asked by At

I have this so far. It works, but I can't help but wonder if there something less hacky.

GET request:

http://localhost:3100/api/things?matches=%7B%22name%22%3A%22asdf%22%7D

decoded: matches={"name":"asdf"} -- I basically take the data object for a GET request, make the keys the query string parameter names and the JSON.stringify value as the query string value.

It works....but I feel like maybe I can do it smoother with an endpoint like:

GET http://localhost:3100/api/things/match/:attr/:value -- but then it's very limiting as I can only have one condition. Whereas passing the whole object above I can match on multiple attributes.

On the Koa side of things, it's not too much extra code (I'm using Thinky for RethinkDB):

  /**
   * list
   * list all things
   * @param next
   */
  ctrl.list = function *(next){
    var matches = this.request.query.matches && JSON.parse(this.request.query.matches);

    if ( matches ) {
      var result = yield Thing.orderBy({index: "createdAt"}).filter(function(doc){
        return doc('name').match(matches.name);
      });
    } else {
      var result = yield Thing.orderBy({index: "createdAt"});
    }

    this.body = result;

    yield next;
  };

If there is no query string, then it just returns all results.

Am I on the right track here?

1

There are 1 answers

2
Tomas Holas On BEST ANSWER

I believe this is the correct way. This approach is used by Baucis, and also koa-mongo-rest with Mongoose. It can be even taken a bit further. An example url like:

/api/users?conditions={"name":"john", "city":"London"}&limit=10&skip=1&sort=-zipcode

Can be processed by following code:

findAll: function*(next) {
  yield next;
  var error, result;
  try {
    var conditions = {};
    var query = this.request.query;
    if (query.conditions) {
      conditions = JSON.parse(query.conditions);
    }
    var builder = model.find(conditions);
    ['limit', 'skip', 'sort'].forEach(function(key){
      if (query[key]) {
        builder[key](query[key]);
      }
    })
    result = yield builder.exec();
    return this.body = result;
  } catch (_error) {
    error = _error;
    return this.body = error;
  }
}

I'd appreciate to have a similar library for RethinkDB as well.