如何使用骨干设计REST搜索

时间:2012-06-19 17:48:04

标签: rest backbone.js

我正在设计一个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吗?不要以为我需要通过ID获取该模型,删除或更新它并不是真的有意义,因为我没有坚持它。

3 个答案:

答案 0 :(得分:10)

我不知道这是一个好习惯, 但我在搜索“fetch”方法中使用“数据”选项。

https://stackoverflow.com/a/6659501/1067061

也许有帮助。 祝你好运!

修改

这是在集合网址中传递查询参数的正确方法, The reference to the Docs显示了如何在fetch选项中传递data属性,data属性实际上是一个对象,其中键值对引用了查询参数及其值

答案 1 :(得分:5)

我会选择选项一。至少一个模型应该对应于单个搜索结果和对整个搜索结果集合的集合。因此,如果您搜索volvo并且返回了6个项目,则每个项目应该是您的集合中包含的模型。

现在,这在很大程度上取决于您在服务器上表示结果的方式。例如,如果您有汽车实例,那么您只需使用查询执行搜索服务器端并将结果对象作为json返回。然后,您可以将返回的列表设置为符合条件的汽车模型集合。但如果您打算以其他方式返回查询结果,那么您将不得不考虑模型应如何表示数据

答案 2 :(得分:0)

我建议使用一个集合,就像在选项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();
});