Come dovrei progettare una risorsa elenco ordinato in un servizio rilassante?

10

Mi sono imbattuto ripetutamente in questo stesso problema e non ho trovato una soluzione che mi sia sembrata ottimale.

In un'app, hai una lista ordinata e consenti all'utente di cambiare l'ordine trascinandolo o qualcosa del genere. Vuoi che le modifiche nell'ordine persistano. Come lo modella?

Come dovrei progettare un servizio riposante di una risorsa elenco ordinato?

In particolare, come dovrei progettare il modello list e item di una risorsa restful? Il design più comune che ho visto è l'entità item con una proprietà order o position . Un altro approccio che ho sentito è una lista doppiamente collegata sugli articoli.

Qual è un approccio che non scrive troppo nel database ed è generalmente veloce da aggiornare e leggere per i clienti? Come dovrebbero essere esposti gli endpoint?

    
posta Rico Kahler 21.09.2016 - 05:56
fonte

1 risposta

10

Rappresentare una lista ordinata è uno dei problemi difficili con i database relazionali. L'aggiunta di una proprietà position alla relazione list-membership è il modo più comune per eseguire questa operazione, poiché è possibile recuperare facilmente l'elenco ordinato aggiungendo ORDER BY position alla query SQL e poiché è possibile inserire facilmente gli elementi nel mezzo dell'elenco calcolando la media dei valori del membro di lista precedente e successivo, assumendo che la posizione sia un float anziché un intero.

Utilizzare elenchi doppiamente concatenati, in quanto è facile rendere inconsistenti i collegamenti e finire con un grafico o un albero ciclici.

Tuttavia, le API RESTful non soffrono delle restrizioni dei database relazionali. Puoi semplicemente fare qualcosa che sembra naturale, piuttosto che usare un hack come una proprietà di posizione.

Se nella lista ci sono solo poche centinaia di elementi, è sufficiente trasferire l'intera lista in una richiesta. Supponendo di voler riordinare [1, 2, 3, 4] dove i membri della lista sono ID, potremmo

POST /url/of/the/list
Content-type: application/json
...

[1, 2, 4, 3]

Il back-end può quindi tradurlo in qualsiasi tecnologia di database che stai utilizzando, ma l'utente API non deve considerare questi dettagli.

Se l'elenco è di grandi dimensioni e gli elementi normalmente richiesti singolarmente, puoi consentire un indice nell'URL:

GET /page/7

Se ti trovi in HATEOAS, la risposta può includere i link prev / next per semplificare la navigazione, se la risorsa di solito viene utilizzata in questo modo. Tuttavia, questo non implica che il tuo database contenga anche questo elenco doppiamente collegato.

Se la lista è molto grande, potresti voler esporre ArrayList -come operazioni come insert o push / append . Potrei immaginare una chiamata come

POST /url/of/the/list?at=1357;mode=insert
...

description of the item to insert

Se il riordino è un caso d'uso comune e il riordino deve essere eseguito immediatamente, allora potresti offrire un endpoint appropriato nella tua API:

POST /url/of/the/list/reorder-item?from=783;to=1357

Se l'elenco riordinato deve essere impegnato in modo esplicito, sarà più facile trasferire il nuovo ordine come documento JSON, vedi sopra.

Ora non è del tutto vero che puoi visualizzare la tua API completamente separata dalla tecnologia del database che stai utilizzando. Tuttavia, è meglio mantenere l'API esterna il più possibile libera dai dettagli di implementazione. Se qualsiasi riordino tocca circa 30 righe solo per aggiornare una colonna di un ordine intero, non è un grosso problema. Basta fare la cosa più semplice possibile e aggiornare sempre l'intera lista. Se la tua bilancia richiede che l'utilizzo del database sia più sofisticato, preferisci catturare questa sofisticazione nel back-end, dove è più facile mantenere la coerenza.

    
risposta data 21.09.2016 - 23:02
fonte

Leggi altre domande sui tag