we need to send all article data back to API for updating and multiuser work could not be implemented. For instance editor could send 5 seconds older data and overwrite fix that some other journalist just did 2 seconds ago and there is no way that I could explain to clients this since those publishing an article is really not in any way connected to updating the content.
Questo genere di cose è una sfida qualunque cosa tu faccia, è un problema molto simile al controllo del codice distribuito (mercurial, git, ecc.), e la soluzione, scritta in HTTP / ReST, sembra un po 'simile.
Supponiamo che tu abbia due utenti, Alice e Bob, entrambi che lavorano su /articles/lunch
. (per chiarezza, la risposta è in grassetto)
In primo luogo, alice crea l'articolo.
PUT /articles/lunch HTTP/1.1
Host: example.com
Content-Type: text/plain
Authorization: Basic YWxpY2U6c2VjcmV0
Hey Bob, what do you want for lunch today?
301 Moved Permanently
Location: /articles/lunch/1
Il server non ha creato una risorsa, perché non c'era nessuna "versione" allegata alla richiesta, (supponendo un identificatore di /articles/{id}/{version}
. Per eseguire la creazione, Alice è stata reindirizzata all'URL dell'articolo / versione lei " verrà creato. L'agente utente di Alice riapplicherà la richiesta al nuovo indirizzo.
PUT /articles/lunch/1 HTTP/1.1
Host: example.com
Content-Type: text/plain
Authorization: Basic YWxpY2U6c2VjcmV0
Hey Bob, what do you want for lunch today?
201 Created
E ora l'articolo è stato creato. poi, bob guarda l'articolo:
GET /articles/lunch HTTP/1.1
Host: example.com
Authorization: Basic Ym9iOnBhc3N3b3Jk
301 Moved Permanently
Location: /articles/lunch/1
Bob guarda lì:
GET /articles/lunch/1 HTTP/1.1
Host: example.com
Authorization: Basic Ym9iOnBhc3N3b3Jk
200 Ok
Content-Type: text/plain
Hey Bob, what do you want for lunch today?
Decide di aggiungere il proprio resto.
PUT /articles/lunch/1 HTTP/1.1
Host: example.com
Content-Type: text/plain
Authorization: Basic Ym9iOnBhc3N3b3Jk
Hey Bob, what do you want for lunch today?
Does pizza sound good to you, Alice?
301 Moved Permanently
Location: /articles/lunch/2
Come con Alice, Bob viene reindirizzato a dove creerà una nuova versione.
PUT /articles/lunch/2 HTTP/1.1
Host: example.com
Content-Type: text/plain
Authorization: Basic Ym9iOnBhc3N3b3Jk
Hey Bob, what do you want for lunch today?
Does pizza sound good to you, Alice?
201 Created
Infine, Alice decide che vorrebbe aggiungere al suo articolo:
PUT /articles/lunch/1 HTTP/1.1
Host: example.com
Content-Type: text/plain
Authorization: Basic YWxpY2U6c2VjcmV0
Hey Bob, what do you want for lunch today?
I was thinking about getting Sushi.
409 Conflict
Location: /articles/lunch/3
Content-Type: text/diff
---/articles/lunch/2
+++/articles/lunch/3
@@ 1,2 1,2 @@
Hey Bob, what do you want for lunch today?
-Does pizza sound good to you, Alice?
+I was thinking about getting Sushi.
Invece di essere reindirizzato come di consueto, viene restituito al client un diverso codice di stato, 409
, che indica ad Alice che la versione da cui stava provando a derivare è già stata ramificata. Le nuove risorse sono state create comunque (come mostrato dall'intestazione Location
) e le differenze tra i due sono state incluse nel corpo della risposta. Alice ora sa che la richiesta che ha appena fatto deve essere unita a un po 'come.
Tutto questo reindirizzamento è correlato alla semantica di PUT
, che richiede che vengano create nuove risorse esattamente dove chiede la linea di richiesta. questo potrebbe anche salvare un ciclo di richieste usando POST
, ma poi il numero di versione dovrebbe essere codificato nella richiesta da qualche altra magia, che mi sembrava meno ovvia ai fini dell'illustrazione, ma sarebbe probabilmente ancora preferibile in una vera API per ridurre al minimo i cicli di richiesta / risposta.