2012-07-23 19 views
10

Ho riflettuto sul metodo corretto per definire le raccolte di risorse che hanno interdipendenza.API REST Progettare collegamenti tra raccolte di risorse

Per esempio, Consente di considerare "documenti" e "commenti", che sono in modo indipendente accessibile tramite l'URI:

/documents/{doc-uri} 
/comments/{comment-id} 

Tuttavia, di solito vogliamo la raccolta di commenti relativi a un documento specifico. Che crea una domanda di design su come questo dovrebbe essere archetected.

posso vedere alcune opzioni principali:

1.) Fornire un URI collezione dopo l'uri documento per i commenti

GET /documents/{doc-uri}/comments/ 

2.) Fornire un parametro per la raccolta commenti per selezionare dal documento

GET /comments/{comment-id}?related-doc={doc-uri} 

3.) Utilizzare la negoziazione dei contenuti per richiedere i relativi commenti vengano reintrodotte attraverso l'intestazione Accept.

// Get all the comments for a document 
GET /documents/{doc-uri} Accept: application/vnd.comments+xml 
// Create a new comment 
POST /documents/{doc-uri} Content-Type: application/vnd.comment+xml <comment>...</comment> 

Metodo 1 ha il vantaggio di mettere automaticamente i commenti nel contesto del documento. Che è anche bello quando si creano, aggiornano ed eliminano commenti usando POST/PUT. Tuttavia non fornisce accesso globale ai commenti al di fuori del contesto di un documento. Quindi, se volessimo effettuare una ricerca su tutti i commenti nel sistema, avremmo bisogno del metodo # 2.

Il metodo 2 offre molti degli stessi vantaggi del numero 1, tuttavia la creazione di un commento senza il contesto di un documento non ha senso. Poiché i commenti devono essere esplicitamente correlati a un documento.

Il metodo 3 è interessante da un punto di vista GET e POST/create, ma diventa piuttosto peloso con l'aggiornamento e l'eliminazione.

Posso vedere pro e contro a tutti questi metodi, quindi sto cercando un altro consiglio da qualcuno che potrebbe aver affrontato e risolto questo problema prima.

Sto prendendo in considerazione l'idea di eseguire entrambi i metodi 1 & 2, quindi posso fornire tutte le funzionalità necessarie, ma sono preoccupato che possa complicare/duplicare eccessivamente le funzionalità.

risposta

9

API REST deve essere gestito da hypermedia. Vedere Hypermedia come il vincolo di Engine of Application State (HATEOAS). Quindi, non sprecare il tuo tempo su URLPatterns, perché non sono RESTful. URLPattern implica un accoppiamento stretto tra un client e un server; semplicemente, il cliente deve essere consapevole di come sono gli URL e ha la capacità di costruirli.

considerare questo disegno REST per il vostro caso d'uso:

La rappresentazione di un documento contiene un link dove il cliente può inviare commenti o con l'utilizzo di ottenere ottenere tutti i commenti sul documento. per esempio.

{ 
    ... 
    "comments" : { 
     "href": ".. url ..", 
     "rel": ["create-new-comment", "list-comments"] 
    } 
} 

Un client accetta questo URL ed esegue il metodo GET o POST nell'URL; senza sapere come è l'URL, sembra.

Vedi anche questo post:

http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

+0

Intendevi ipermedia, non ipertesto. Questa è la parte HATEOAS (http://en.wikipedia.org/wiki/HATEOAS) di REST. – jpbochi

0

La combinazione dei metodi 1 e 2 sembra buono, come si dice in metodo 2, non hanno molto senso creare commenti senza un contesto documento dal momento che un esiste una relazione genitore-figlio tra entrambi, se si cancella un documento è accettabile per eliminare anche tutti i suoi commenti, è possibile rendere il tuouri una risorsa di sola lettura al fine di evitare la sua creazione senza un documento.

Come filip26 dice che l'apis di riposo dovrebbe essere guidato dall'ipermedia ma ciò non significa che i pattern di URL non sono importanti, potresti avere una risorsa con un uri o molti, se le tue risorse hanno più uris è più facile per i client trovarle , il lato negativo è che potrebbe essere fonte di confusione perché alcuni client usano un uri invece di un altro, quindi puoi usare un uri canonico per una risorsa, quando un client accede a una risorsa attraverso questo uri canonico puoi mandare indietro un 200 OK, quando una richiesta client uno degli altri uri puoi mandare indietro un 303 "Vedi anche" insieme con lo uri canonico.