Использование HATEOAS и Backbone.js - PullRequest
12 голосов
/ 01 марта 2012

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

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

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

Кто-нибудь расширял / строил Backbone, чтобы он делал это? Может быть, опираясь на «стандарт», как 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 автоматически извлекалось из ссылки на себя в HAL. Я думаю, создание новой базовой модели что-то вроде (не проверено):

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

Мысли

Ответы [ 4 ]

10 голосов
/ 31 мая 2012

Я расширил магистраль, чтобы сделать именно это, библиотека доступна здесь:

https://github.com/mikekelly/backbone.hal

4 голосов
/ 02 марта 2012

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

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

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

parse: function(response) {
    this.url = response._links.self;
    delete response._links;
    return response;
}
2 голосов
/ 02 июля 2015

Я дополняю здесь ответ Саймона, чтобы объяснить, как легко это сделать, используя 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 (), которая является более мощной, чем стандартный URL-адрес Backbone (), и которая очень полезна, если вы используете 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, если вам нужна помощь в этом.

1 голос
/ 01 марта 2012

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

...