2012-03-01 10 views
12

Я начал экспериментировать с Backbone.js и был поражен документацией для документации для свойства url на Backbone.Model.Использование HATEOAS и Backbone.js

В частности, я создаю REST API, который использует HATEOAS/hypermedia для управления клиентом (ами).

Я могу видеть полезность поведения по умолчанию для построения базовых объектов для создания самих URL-адресов для элементов в коллекции, но для моего случая предпочла бы, чтобы URL-адреса модели были построены из анализируемых данных.

Кто-нибудь расширил/построил на Магистраль, чтобы заставить это сделать это? Может быть, основывается на «стандарте», таком как HAL?

EDIT:

Для разъяснения, скажем, у меня есть следующие:

GET/заказов >>

[ 
    { 
    "_links": { 
     "self": "/orders/123" 
    } 
    "name": "Order #123", 
    "date": "2012/02/23" 
    }, 
    { 
    "_links": { 
     "self": "/orders/6666" 
    } 
    "name": "Order #666", 
    "date": "2012/03/01" 
    }, 
] 

и у меня есть модель заказа, как:

var Order = Backbone.Model.extend({ 
}); 

Я хотел бы url свойство автоматически вытаскивается из ссылки «self» в HAL. Я думаю, что создание новой базовой модели примерно так (не проверено):

var HalModel = Backbone.Model.extend({ 
    url: function() { 
    return get("_links").self; 
    }, 
}); 

Мысли?

+0

Вы говорите, что если у вас есть модель заказа, в которой вы хотите, чтобы Url был динамически настроен на «order/{orderid}», и если у вас есть модель клиента, то тот же код установил бы его «customer/{customerid } '? – timDunham

+0

@timDunham Смотрите мои правки для уточнения. – Pete

ответ

4

Спасибо за разъяснение @Pete.

Я думаю, что вижу, что вы предлагаете, и я полагаю, что это может сработать. Однако в вашем примере вам сначала нужно было узнать URL-адрес /Orders, прежде чем вы сможете получить заказы. И если вы переработали свой json, чтобы иметь свойство id, вы бы приблизились к стандартной архитектуре магистрали по умолчанию.

Теперь, если вы просто хотите использовать общую модель или базовую модель (например, HALModel) и просто загрузите ее с данными, ваш подход может быть полезен и определенно может работать. Тем не менее, я хотел бы посмотреть на переопределение parse тянуть URL, и установить его на модели:

parse: function(response) { 
    this.url = response._links.self; 
    delete response._links; 
    return response; 
} 
+0

Да, зная, что URL-адрес/orders отправляется из GET в базовый URL-адрес службы, который с использованием подхода HATEOAS возвращает ссылки для всех доступных ресурсов: GET/>> {"_links": {"urn: mysite. com: orders ":"/orders "} – Pete

+0

Мне нравится использование функции синтаксического анализа. Нужно ли подключаться к методу базового разбора с помощью Backbone.Model.prototype.parse.call (это, ответ); ? – Pete

+1

Не нужно цепляться. По умолчанию 'parse' возвращает' response'. – timDunham

1

Вы можете переопределить функцию url на модели, чтобы вычислить URL-адрес, какой бы вы ни хотели; он полностью расширяем.

+0

Да, я видел, что могу переопределить его вручную для конкретной модели. Мне любопытно, есть ли у кого-то более общий/многоразовый подход, который они использовали. – Pete

2

Я дополняю здесь ответ Саймона, чтобы объяснить, как легко это сделать, используя gomoob/backbone.hateoas.

// Instanciation of an Hal.Model object is done the same way as you're 
// used to with a standard Backbone model 
var user = new Hal.Model({ 
    firstName: "John", 
    lastName: "Doe", 
    _links: { 
     avatar: { 
      href: "http://localhost/api/users/1/avatar.png" 
     }, 
     self: { 
      href: "http://localhost/api/users/1" 
     } 
    }, 
    _embedded: { 
     address: { 
      "city" : "Paris", 
      "country" : "France", 
      "street" : "142 Rue de Rivoli", 
      "zip" : "75001", 
      "_links" : { 
       "self" : { 
        "href" : "http://localhost/api/addresses/1" 
       } 
      } 
     } 
    } 
}); 

// Now we you can easily get links, those lines are equivalent 
var link1 = user.getLink('avatar'); 
var link2 = user.getLinks().get('avatar'); 

// So getting self link is simple too 
var self = user.getLink('self'); 

// All the Hal.Link objects returned by backbone.hateoas are in fact 
// standard Backbone models so its standard Backbone 
link1.get('href'); 
link1.getHref(); 

// You can do more with shortcut methods if your HAL links 
// have more properties 
link1.get('deprecation'); 
link1.getDeprecation(); 
link1.get('name'); 
link1.getName(); 
link1.get('hreflang'); 
link1.getHreflang(); 
link1.get('profile'); 
link1.getProfile(); 
link1.get('title'); 
link1.getTitle(); 
link1.get('type'); 
link1.getType(); 
linke1.get('templated'); 
link1.isTemplated(); 

// You can also manipulate embedded resources if you need 
user.getEmbedded('address').get('city'); 
user.getEmbedded('address').getLink('self'); 
... 

Наконец мы обеспечиваем реализацию Hal.Model.url(), который является более мощным, чем стандартный Backbone URL() и что очень полезно, если вы используете HAL.

// By default url() returns the href of the self link if this self 
// link is present 
user.url(); 

// If the self link is not defined then url() has the same behavior 
// as standard Backbone url() method 
// My user is link to a user collection having a URL equal to 
// 'http://localhost/user1' 
user.url(); // http://localhost/users/1 

// My user is not link to a user collection in this case the URL is 
// generate using the model urlRoot property by default 
user.urlRoot = 'http://myserver/users'; 
user.url(); // http://localhost/users/1 

// backbone.hateoas also allows you to define an application wide root 
// URL which prevent to use absolute URLs everywhere in your code 
Hal.urlRoot = 'http://localhost/api'; // HAL root API URL 

var user = new Hal.Model({ id : 1}); 
user.urlMiddle = 'users'; 
user.url(); // http://localhost/api/users/1 

Надеюсь, что это поможет, не стесняйтесь публиковать вопросы о нашем github, если вам нужна помощь в этом.

Смежные вопросы