2012-03-01 4 views
12

Ho iniziato a sperimentare con Backbone.js e sono rimasto colpito dalla documentazione relativa alla documentazione per la proprietà url su Backbone.Model.Utilizzo di HATEOAS e Backbone.js

In particolare, sto costruendo un'API REST che utilizza HATEOAS/hypermedia per guidare i client.

posso vedere l'utilità del comportamento predefinito di Backbone di costruire URL stesso per gli elementi in una collezione, ma per il mio caso, preferirebbero avere gli URL modello costruito fuori dei dati che viene analizzato.

Qualcuno ha esteso/costruito su Backbone per farlo funzionare? Forse basandosi su uno "standard" come HAL?

EDIT:

Per chiarimenti, diciamo che ho il seguente:

GET/ordini >>

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

e ho un Modello di ordine come:

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

Vorrei lo url proprietà da estrarre automaticamente dal riferimento "self" nell'HAL. Penso che la creazione di un nuovo modello di base qualcosa di simile (non testato):

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

Pensieri?

+0

Sta dicendo che se si dispone di un modello di ordine che si desidera che l'URL da impostare in modo dinamico al 'ordine/{orderid}' e se si dispone di un modello di cliente, lo stesso codice sarebbe impostarla su 'cliente/{customerid } '? – timDunham

+0

@timDunham Vedi la mia modifica per ulteriori chiarimenti. – Pete

risposta

4

Grazie per il chiarimento @Pete.

Penso di vedere che cosa propongono e suppongo che possa funzionare. Tuttavia, nel tuo esempio, devi prima conoscere l'url /Orders prima di poter ricevere gli ordini. E se hai rielaborato il tuo json per avere una proprietà id, saresti abbastanza vicino all'implementazione predefinita del backbone.

Ora, se si desidera utilizzare solo un modello generico o un modello di base (ad esempio HALModel) e semplicemente il bootstrap con dati, l'approccio potrebbe essere utile e sicuramente potrebbe funzionare. Tuttavia, vorrei guardare sovrascrivendo parse per tirare fuori l'url e metterlo sul modello:

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

Sì, sapendo che l'URL/orders proviene da un GET all'URL di base per il servizio, che utilizzando un approccio HATEOAS restituisce i collegamenti per tutte le risorse disponibili: GET/>> {"_links": {"urna: mysite. com: orders ":"/orders "} – Pete

+0

Mi piace l'uso della funzione parse. Devo concatenare il metodo di analisi di base con Backbone.Model.prototype.parse.call (this, response); ? – Pete

+1

Non è necessario concatenare. Per impostazione predefinita 'parse' return' response'. – timDunham

1

È possibile sovrascrivere la funzione url sul modello per calcolare l'URL come desiderato; è completamente estensibile.

+0

Sì, ho visto che posso sovrascriverlo manualmente per un modello particolare. Sono curioso di sapere se qualcuno ha un approccio più generico/riutilizzabile che hanno adottato. – Pete

2

Complemento qui la risposta di Simon per spiegare come farlo facilmente usando 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'); 
... 

Infine fornire un'implementazione Hal.Model.url(), che è più potente di url Backbone standard() e che è molto utile se si utilizza 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 

Spero che questo aiuti, non esitare a pubblicare le questioni sul nostro github se hai bisogno di aiuto su questo.