2015-06-12 3 views
0

У меня это до сих пор. Это работает, но я не могу не задаться вопросом, есть ли что-то менее взломанное.Как отправить запрос GET на бэкэнд koa, который будет возвращать условные результаты?

запрос GET:

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

декодируется: matches={"name":"asdf"} - Я в принципе взять объект данных для запроса GET, сделать ключи имена параметров строки запроса и значение JSON.stringify в качестве значения строки запроса.

Он работает .... но я чувствую, что, возможно, я могу сделать ее более гладкой с конечной точкой, как:

GET http://localhost:3100/api/things/match/:attr/:value - но это очень ограничивает, как я могу иметь только одно условие. В то время как передача всего объекта выше, я могу сопоставлять несколько атрибутов.

На стороне Коа вещей, это не слишком много дополнительного кода (я использую Thinky для 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; 
    }; 

Если нет строки запроса, то он просто возвращает все результаты.

Я нахожусь на правильном пути здесь?

+0

Я не знаю много koa, просто комментарий по вашему выбору конечной точки: если вы используете '/: attr /: value', вы не будете передавать несколько терминов запроса следующим образом:' ../matches/name/asdf/color/red/prop/value ... '?? Кажется .. неудобно. Разве не лучше было бы анализировать их как строки запросов? '../ matches? name = asdf & color = red & prop = val' – laggingreflex

+0

Идея с подходом к строкам запроса состоит в том, что я мог бы передать несколько объектов фильтра как' matches = {name: 'asdf'} & where = {age: 18} 'etc и т. д. – chovy

+0

Кажется, что, хотя хак, ваше решение, вероятно, является самым гибким. Вы просто хотите иметь уровень HTTP поверх своих моделей, или интерфейс будет более ограниченным? –

ответ

2

Я считаю, что это правильный путь. Этот подход используется Baucis, а также koa-mongo-rest с Mongoose. Его можно даже принять немного дальше. Пример URL, как:

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

Может быть обработан следующим кодом:

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; 
    } 
} 

Я оценил бы иметь подобную библиотеку для RethinkDB, а также.

+0

Существует http://thinky.io для RethinkDB – chovy

+0

ОК, но подумайте, если вам нужно пойти дальше и указать свойство имени. Допустим, что имя было фактически объектом, и у него были такие свойства, как full, nick и т. Д. Как бы вы начали указывать более низкую цепочку иерархии в ресурсе, который имеет свойства, и в одном из тех свойств, которые вы хотите получить до его свойства, и так далее, чтобы установить как критерии. Я вижу, что это работает только на том же уровне иерархии ресурса, который вы запрашиваете, поэтому я не вижу, чтобы он обрабатывал более сложные случаи. – PositiveGuy

+0

Не могли бы вы просто использовать точечную нотацию? (см. http://stackoverflow.com/questions/12842632/mongodb-query-slow-with-dot-notation) –