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.
Esse tipo de coisa é um desafio, não importa o que você faça, é um problema muito similar ao controle de fonte distribuída (mercurial, git, etc.), e a solução, escrita em HTTP / ReST, parece um pouco similar. / p>
Suponha que você tenha dois usuários, Alice e Bob, ambos trabalhando em /articles/lunch
. (para maior clareza, a resposta está em negrito)
Primeiro, Alice cria o artigo.
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
O servidor não criou um recurso, pois não havia "versão" anexada ao pedido, (assumindo um identificador de /articles/{id}/{version}
. Para realizar a criação, Alice foi redirecionada para o URL do artigo / versão ela ' O agente do usuário de Alice reaplicará a solicitação no novo endereço.
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 agora o artigo foi criado. Em seguida, Bob olha para o artigo:
GET /articles/lunch HTTP/1.1
Host: example.com
Authorization: Basic Ym9iOnBhc3N3b3Jk
301 Moved Permanently
Location: /articles/lunch/1
Bob olha para 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?
Ele decide adicionar sua própria alteração.
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
Assim como Alice, Bob é redirecionado para onde ele criará uma nova versão.
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
Finalmente, Alice decide que gostaria de adicionar ao seu próprio artigo:
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.
Em vez de ser redirecionado normalmente, um código de status diferente é retornado ao cliente, 409
, que informa a Alice que a versão da qual ela estava tentando ramificar já foi ramificada. Os novos recursos foram criados de qualquer maneira (conforme mostrado pelo cabeçalho Location
) e as diferenças entre os dois foram incluídas no corpo da resposta. Alice agora sabe que o pedido que ela acabou de fazer precisa ser mesclado de alguma forma.
Todo esse redirecionamento está relacionado à semântica de PUT
, que requer que novos recursos sejam criados exatamente onde a linha de solicitação é solicitada. Isso também poderia salvar um ciclo de solicitação usando POST
, mas o número da versão teria que ser codificado na solicitação por alguma outra mágica, o que parecia menos óbvio para mim para fins de ilustração, mas provavelmente ainda seria preferível em uma API real para minimizar os ciclos de solicitação / resposta.