dobbiamo inviare tutti i dati dell'articolo all'API per l'aggiornamento e non è stato possibile implementare il lavoro multiutente. Ad esempio, l'editor potrebbe inviare dati più vecchi di 5 secondi e sovrascrivere la correzione che qualche altro giornalista ha appena fatto 2 secondi fa e non c'è modo che io possa spiegarlo ai clienti poiché coloro che pubblicano un articolo non sono in alcun modo collegati all'aggiornamento del contenuto.
Questo genere di cose è una sfida, qualunque cosa tu faccia, è un problema molto simile al controllo del codice sorgente distribuito (mercurial, git, ecc.) E la soluzione, scritta in HTTP / ReST, sembra un po 'simile.
Supponiamo che tu abbia due utenti, Alice e Bob, che stanno entrambi lavorando /articles/lunch
. (per chiarezza, la risposta è in grassetto)
Innanzitutto, 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, in quanto non vi era alcuna "versione" allegata alla richiesta (presupponendo un identificatore di /articles/{id}/{version}
. Per eseguire la creazione, Alice è stata reindirizzata all'URL dell'articolo / versione che creerà. L'utente di Alice l'agente applicherà nuovamente 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 la propria modifica.
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, al client viene restituito un codice di stato diverso 409
, che indica ad Alice che la versione da cui stava tentando di eseguire il branch è già stata ramificata. Le nuove risorse sono state comunque create (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 in qualche modo.
Tutto questo reindirizzamento è correlato alla semantica di PUT
, che richiede che vengano create nuove risorse esattamente dove viene richiesta la riga di richiesta. questo potrebbe anche salvare un ciclo di richiesta usando POST
invece, ma poi il numero di versione dovrebbe essere codificato nella richiesta da qualche altra magia, che mi è sembrata meno ovvia ai fini dell'illustrazione, ma probabilmente sarebbe comunque preferito in una vera API per ridurre al minimo i cicli di richiesta / risposta.
api/article?action=publish
? I parametri di query sono destinati a tali casi in cui lo stato della risorsa dipende dall'algoritmo (o dall'azione) di cui si parla. Ad esempioapi/articles?sort=asc
è valido