2012-02-07 12 views
8

Supponiamo che volessi progettare un'API REST che parla di canzoni, album e artisti (in realtà faccio, come 1312414 persone prima di me).RESTful modo di affrontare le relazioni bidirezionali tra le risorse

Una risorsa di song è sempre associata all'album di cui fa parte. Al contrario, la risorsa dell'album è associata a tutti i brani che contiene. Le associazioni sono espresse nelle rappresentazioni delle risorse tramite link.

Come tali, le rappresentazioni sarebbero simile a questa:

{ 
    song: 'xyz', 
    links: [ 
     { rel: 'album', url: '.../albums/abc' } 
    ] 
} 

{ 
    album: 'abc', 
    links: [ 
     { rel: 'song', url: '.../songs/xyz' }, 
     { rel: 'song', url: '...' }, 
     { rel: 'song', url: '...' }, 
     { rel: 'song', url: '...' } 
    ] 
} 

Dato, che voglio questo per tenere vero (forse il problema sta nel "Data"), allora come faccio a progettare il mio API , in modo tale che la creazione di un album o di una risorsa di brani non abbia effetti collaterali sulle risorse di brani o album precedentemente esistenti?

Questa è una specie di problema uovo/pollo. Se creo prima una risorsa canzone (POST/songs /) e poi creo una risorsa album (POST/albums /), la risorsa del brano viene modificata come parte della creazione dell'album (che è male secondo i principi REST), perché l'associazione tra le due risorse viene aggiornato sul server. Allo stesso modo per lo scenario in cui creo per primo l'album, il secondo della canzone.

Immagino di poter evitare l'intero problema evitando l'effetto collaterale sul server e passando l'onere di gestire le relazioni bidirezionali con il cliente.

Inoltre, non voglio che l'album e le canzoni vengano creati atomicamente nel loro complesso.

L'unica cosa che riesco a pensare al momento, è includere il suddetto effetto collaterale nella semantica della mia API rispondendo a una creazione di risorse con una rappresentazione che contiene un elenco di collegamenti a risorse che sono state modificate come risultato della richiesta. Questo rende esplicito l'effetto collaterale, ma non è comunque riposante.

+0

creare un brano, se ha un campo album e l'album non esiste, creare l'album. crea un album, se ha una canzone che non esiste, crea la canzone. – zzzzBov

+0

Un modo per guardarlo è che ogni album e canzone è una risorsa incapsulata e i collegamenti sono solo il grafico che li connette tra loro. La modifica dei collegamenti modifica la relazione tra le risorse ma le risorse non cambiano effettivamente. – abraham

+3

"la risorsa del brano viene modificata come parte della creazione dell'album (che è male secondo i principi REST)" Quale principio è questo? Puoi fornire un collegamento? Nella mia esperienza l'aggiornamento delle risorse ha sempre effetti collaterali su altre risorse. –

risposta

1

Niente di REST dice che la manipolazione dello stato di una risorsa non può alterare lo stato di un'altra risorsa. A proposito del REST che si avvicina di più è la nozione di azioni idempotenziali, che dicono solo che la ripetizione di esse avrà come risultato lo stesso stato.

Quindi, nel tuo caso, non c'è nulla di intrinsecamente scorretto in una risorsa Song che sia in grado, in effetti, di aggiungersi a una risorsa Album. Né c'è qualcosa di intrinsecamente sbagliato in una risorsa Album in grado di dire che una risorsa Song è una parte di essa.

Ora, date le vostre esigenze di business, potreste volere o a.) Cambiare il modo in cui rappresentate i brani/album o b. Permettete che i brani/album siano correlati in modo m/m invece di 1/1. La ragione di ciò è che, a seconda di come strutturate i vostri dati e selezionate le risorse (cioè le unità indirizzabili) nel vostro sistema, state effettivamente modellando relazioni di dati differenti, e questo, penso, è il punto cruciale del problema che state affrontando .

Con Songs e Albums risorse separate nel sistema, l'applicazione di relazioni più restrittive, come 1/1 anziché m/m, richiede molto più lavoro e specifiche nei tipi di contenuto. Devi gestire i casi in cui due album diversi pensano di contenere una singola canzone, ma una relazione 1/1 non lo consente.

Se si dispone di un oggetto in modo esplicito Albumcontenere o propri gli Song oggetti, poi c'è meno di un problema, dal momento che un Album può manipolare solo che è proprie canzoni e non quelli di qualsiasi altro Album. Questo modifica il modello di dati poiché Songs non sono più cittadini di prima classe, ma invece sono sotto l'album che li possiede.

Questo è il punto chiave dell'intero problema ... è necessario decidere chi possiede la relazione.

Non c'è niente di sbagliato in entrambi i lati (Album e Song) possederlo. Ciò funziona perfettamente per una relazione m/m, ma per una relazione 1/1, ciò richiede un sovraccarico di gestione molto maggiore (ad esempio qualcos'altro possiede effettivamente la relazione).

Se si desidera un rapporto di 1/1 senza tutte le spese generali, tuttavia, è necessario disporre di uno dei soggetti che partecipano possiedono il rapporto, il che significa che c'è solo uno percorso di cambiarlo ... attraverso l'entità proprietaria.

Problemi correlati