Как создать поиск REST с основой

Я разрабатываю API, а также потребляю его с помощью Backbone.js. Часть API будет включать операции поиска. Например, при поиске автомобилей у меня может быть что-то вроде:

http://api.mysite.com/search/cars?q=volvo

С позвоночником я вижу два варианта использования результатов.

Вариант 1: Поиск представляет собой коллекцию

var CarSearch = Backbone.Collection.extend({
    model: Car,
    initialize : function(models, options){
        this.query = options.query;
    },
    url: function(){
        return "http://api.mysite.com/search/cars?q="+this.query;
    }
});

var volvos = new CarSearch([], {query:'volvo'});
volvos.fetch();

Вариант 2: поиск - это модель, и результатом является коллекция

var CarSearchResults = Backbone.Collection.extend({
    model: Car
});

var CarSearch = Backbone.Model.extend({
    defaults: {
        "query":"",
        "carSearchResults":null
    },
    url: function(){
        return "http://api.mysite.com/search/cars?q="+this.get('query');
    },
    parse: function(resp,xhr){
        resp.carSearchResults = new CarSearchResults(resp.carSearchResults);
        return resp;
    }
});

var volvoSearch = new CarSearch();
volvoSearch.set({query:'volvo'});
volvoSearch.save();

Каковы преимущества/недостатки этих вариантов? Есть ли способ создания этого позвоночника?

Я склоняюсь к варианту 2, потому что кажется более легким добавить что-то к ответу, например, к деталям разбиения на страницы, или к следующему URL-адресу. Но вариант 2 кажется более беспорядочным по-разному. Например, я бы сгенерировал идентификатор на сервере для модели поиска, когда он будет сохранен? Не думайте, что мне нужно получить эту модель по ID, удаление или обновление ее на самом деле не имеет смысла, потому что я не сохраняю ее.

Ответы

Ответ 1

Я бы пошел с вариантом один. По крайней мере, модель imo должна соответствовать единому результату поиска и коллекциям для всего набора результатов поиска. поэтому, если вы ищете volvo и есть 6 возвращенных предметов, каждый элемент должен быть моделью, содержащейся в вашей коллекции.

Теперь это будет во многом зависеть от того, как вы представляете результат на своем сервере. Если вы скажете, например, что у вас есть экземпляры автомобилей, вы просто используете сторону поискового сервера, используя запрос, и возвращаете результирующие объекты как json. Тогда вы можете вернуть возвращенный список в коллекцию моделей автомобилей, которые соответствуют критериям. но если вы планируете возвращать результаты запроса другим способом, вам придется подумать о том, как модель должна представлять данные.

Ответ 2

Я не знаю, хорошая ли практика, но я использую для своего поиска опцию "данные" в методе "выборки".

fooobar.com/questions/41165/...

Может быть, это помогает. Удачи!

ИЗМЕНИТЬ

Это правильный способ передать параметры запроса в своих URL-адресах коллекций, Ссылка на Документы показывает, как передать атрибут данных в параметрах выборки, атрибут data фактически является объектом с парами значений ключа, относящимися к запросу params и их значения

Ответ 3

Я бы рекомендовал использовать коллекцию, как в варианте 1, но без необходимости определять новую коллекцию только для поиска.

Взгляните на мое сообщение в блоге об этом здесь: http://willdemaine.ghost.io/restful-search-with-backbone/

var SearchableCollection = Backbone.Collection.extend({},{

  search: function(query, options){
    var search = $.Deferred();
    options = options || {};
    var collection = new this([], options);
    collection.url = _.result(collection, 'url') + 'search?q=' + query;
    var fetch = collection.fetch();
    fetch.done(_.bind(function(){
      Backbone.Events.trigger('search:done');
      search.resolveWith(this, [collection]);
    }, this));
    fetch.fail(function(){
      Backbone.Events.trigger('search:fail');
      search.reject();
    });
    return search.promise();
  }

});

Затем вы можете сделать:

var Cars = SearchableCollection.extend({});

var findCars = Cars.search('volvo');  
findCars.done(function(cars){  
  var carsView = new CarsView({
    collection: cars
  });
  carsView.render();
});