RESTful API / Data Modeling - Come modellare una risorsa subordinata che avrà sempre e solo un elemento

3

Sto creando un'API e un modello di dati per un'applicazione di creazione di documenti multiutente e sto riscontrando problemi con una parte particolare del modello di dati / progettazione dell'API. Di seguito la mia linea di pensiero corrente:

Ci sono due azioni simili che possono accadere mentre un utente sta scrivendo un documento:

  1. Un utente può salvare manualmente un documento. Questo crea una revisione e possono esserci molte revisioni per un singolo documento.
  2. Un autosalvataggio viene attivato periodicamente mentre un utente sta modificando il documento. Poiché le operazioni di salvataggio automatico possono svolgersi abbastanza frequentemente e disporre di dati ridondanti, può esistere un solo salvataggio automatico per un singolo documento.

Queste azioni sono utilizzate per creare un paio di funzioni:

  1. Gli utenti possono ripristinare una vecchia revisione del documento.
  2. Le salvataggi automatici impediscono all'utente di perdere il proprio lavoro.
  3. Blocco del documento di base: se un utente crea un salvataggio automatico per un documento, un altro utente non può iniziare a modificarlo. Quando un utente attiva un salvataggio manuale, creando una revisione, il salvataggio automatico associato al documento verrà eliminato e quindi un altro utente potrebbe iniziare a lavorare sul documento.

Ecco uno schema del modello di dati che ho:

 _________           ______________________
|Documents|         |DocumentRevisions     |
|---------| ------< |----------------------|    
|id: int  |         |id: int               |
|_________|         |documentBody: string  |
     |              |createdAt: datetime   |
     |              |______________________|
 ____|________________
|DocumentDrafts       |
|---------------------|
|id: int              |
|documentBody: string |
|_____________________|

E qui ci sono alcuni degli endpoint che ho:

  • RICEVI / documenti /
  • POST / documenti // revisioni
    • Questo è chiamato su un salvataggio manuale
  • PUT / documenti // bozza
    • Questo è chiamato su autosave

Queste sono le cose che non mi piacciono di questo modello attuale:

  • L'endpoint POST /documents/<documentId>/revisions deve anche modificare la tabella DocumentDrafts per riflettere il fatto che il documento è ora in uno stato "pulito" e può essere modificato da un altro utente
  • L'endpoint PUT /documents/<documentId>/draft interrompe alcune regole di REST incluso l'uso della singola parola "bozza" (perché può esserci solo una bozza di un documento)

Penso che il requisito che un solo salvataggio automatico possa esistere per un documento in qualsiasi momento mi fa davvero inciampare e non sono sicuro di come modellarlo correttamente. Esiste un modo migliore? Devo sollevare il requisito di un singolo salvataggio automatico per documento?

    
posta mplis 21.04.2016 - 22:35
fonte

1 risposta

3

The POST /documents/<documentId>/revisions endpoint has to also modify the DocumentDrafts table to reflect the fact that the document is now in a "clean" state and can be modified by another user

Livello diverso. È importante capire che di solito non è consigliabile accoppiare strettamente il livello API al servizio e / o ai livelli di dati.

The PUT /documents/<documentId>/draft endpoint breaks a few rules of REST including the use of the singular word "draft" (because there can only be one draft of a document)

Non esiste una regola del genere. Per cominciare, REST non dice esattamente nulla su come dovrebbero apparire gli URI. Oltre a ciò, è generalmente accettato nel design dell'API Web che le singole parole siano ragionevoli quando esiste un'unica istanza della risorsa.

Nei tuoi panni, userei questi endpoint:

/documents
/documents/{id}
/documents/{id}/draft
/revisions
/revisions/{id}

Un utente può ottenere un documento. Questo conterrà un link o una sottorisorsa con la revisione più recente. Per iniziare a modificare, POST per il draft. Ciò restituirà 201 Created (stanno ora modificando) o 409 Conflict (qualcun altro sta già modificando). L'utente che sta modificando sarà PUT in bozza. Per annullare la modifica senza salvare, l'utente può DELETE bozza. Per impegnare la bozza, POST a / revisioni. Un effetto collaterale di questo sarà quello di eliminare la bozza. In alternativa, puoi richiedere una DELETE manuale di bozza da parte del client per terminare la modifica.

Ora l'unico problema che hai è quello che succede quando l'utente inizia una modifica e va in vacanza senza annullarlo o commetterlo. : -)

    
risposta data 22.04.2016 - 15:35
fonte

Leggi altre domande sui tag