Использование HATEOAS и Backbone.js
Я начал экспериментировать с Backbone.js и был поражен документацией для документации для свойства url на Backbone. Модель.
В частности, я создаю REST API, который использует HATEOAS/hypermedia для управления клиентом (-ами).
Я вижу полезность поведения по умолчанию для базового поведения для создания самих URL-адресов для элементов в коллекции, но для моего случая предпочитаю, чтобы URL-адреса модели были построены из анализируемых данных.
Кто-нибудь расширил/построил на Магистраль, чтобы заставить это сделать это? Возможно, основываясь на "стандарте", например HAL?
EDIT:
Для пояснения, скажем, у меня есть следующее:
GET/orders →
[
{
"_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;
},
});
Мысли?
Ответы
Ответ 1
Спасибо за разъяснение @Pete.
Я думаю, что вижу, что вы предлагаете, и я полагаю, что это может сработать. Однако в вашем примере вам сначала нужно было узнать URL /Orders
, прежде чем вы сможете получить заказы. И если вы переработали свой json, чтобы иметь свойство id
, вы бы приблизились к стандартным реализациям магистрали.
Теперь, если вы просто хотите использовать общую модель или базовую модель (например, HALModel
) и просто загружать ее с данными, ваш подход может быть полезен и определенно может работать. Однако я бы посмотрел на переопределение parse, чтобы вытащить URL-адрес и установить его на модели:
parse: function(response) {
this.url = response._links.self;
delete response._links;
return response;
}
Ответ 2
У меня расширенная основа, чтобы сделать именно это, библиотека доступна здесь:
https://github.com/mikekelly/backbone.hal
Ответ 3
Я дополняю здесь ответ Саймона, чтобы объяснить, как легко это сделать, используя 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, если вам нужна помощь в этом.
Ответ 4
Вы можете переопределить функцию url на модели, чтобы вычислить URL-адрес, какой бы вы ни хотели; он полностью расширяемый.