How to implement HTTP's PUT that works with child collections when using DDD's rich domain models?
Con grande difficoltà.
PUT , come DELETE e PATCH , hanno semantica di authoring remoto. "Rendi la risorsa simile a questa".
L'idea di base è che posso prendere qualsiasi editor HTTP che capisca il tipo di media, e usarlo per caricare una nuova rappresentazione, apportare modifiche ad esso, quindi memorizzare le modifiche - senza bisogno di sapere nulla su come l'origine il server memorizza tali informazioni.
Pertanto, l'onere è sul server per capire come convertire la nuova rappresentazione in comandi da inviare alla propria memoria di supporto.
Una possibile risposta è mettere più peso sul tuo tipo di media. Le risorse possono avere più di una rappresentazione e non è necessario supportare PUT
per tutte loro. 415 Unsupported Media Type
è lì per te nel caso in cui tu debba rifiutare un PUT
che non puoi convertire in messaggi che il tuo modello di dominio comprenderà.
Il flusso potrebbe essere simile a
GET /foo
Content-Type: application/json
E il consumatore che guarda questa rappresentazione vede che desidera modificare la risorsa. Quindi chiede la rappresentazione modificabile
GET /foo
Content-Type: application/vnd.hacky-workarounds.edit+json
PUT /foo
Content-Type: application/vnd.hacky-workarounds.edit+json
Potresti immaginare una rappresentazione analoga a application / json-patch + json , con operazioni che corrispondono al messaggio di comando che il tuo modello di dominio comprende e operazioni di query che descrivono lo stato iniziale (ad esempio, l'hash dell'albero corrente).
A seconda dello schema, il client potrebbe essere in grado di convertire il DTO originale nella rappresentazione modificabile da solo, senza dover eseguire un GET. HTTP è senza stato, quindi il successivo PUT
dovrebbe comportarsi allo stesso modo a prescindere.
Un altro approccio da considerare è che il modello di dominio ha due responsabilità: assicurarsi che lo stato sia internamente coerente e assicurarsi che le transizioni siano valide. In altre parole, il server di origine non ha necessariamente bisogno di applicare le stesse regole aziendali, ma invece di verificare che le regole siano state applicate correttamente.
Pertanto, verifichi che il DTO sia internamente coerente e controlli che la transizione dallo stato precedente a quello nuovo sia legale, e se entrambi ti trattengono tieni semplicemente il risultato senza preoccuparti di ripetere il lavoro da solo.
Ma la vera risposta è quella che odi - diff le due rappresentazioni, decodificare i comandi necessari per trasformare l'una nell'altra e quindi applicare tali comandi tramite il modello di dominio.
PUT può essere usato per creare risorse, oltre a modificarle (a condizione che tu sia a tuo agio con la nozione che un client ottiene un certo controllo dell'URI). Quindi potresti mettere una rappresentazione di un messaggio di comando in qualche nuova risorsa. Probabilmente vorresti utilizzare l'intestazione If-None-Match per assicurarti che l'URI particolare non sia già occupato . Quindi ogni comando otterrebbe un URI univoco, selezionato dal client. Quello che non ottieni in quel caso è l'invalidazione della cache del DTO (che ha già il proprio URI)
Permettere al client di selezionare un URI per la risorsa del messaggio di comando è analogo a consentire al client di selezionare il proprio identificatori di correlazione .