debemos enviar todos los datos del artículo a la API para actualizarlos y no se pudo implementar el trabajo multiusuario. Por ejemplo, el editor podría enviar datos anteriores de 5 segundos y sobrescribir la corrección que algún otro periodista acaba de hacer hace 2 segundos y no hay forma de que pueda explicárselo a los clientes, ya que aquellos que publican un artículo no están conectados de ninguna manera para actualizar el contenido.
Este tipo de cosas es un desafío sin importar lo que hagas, es un problema muy similar al control de fuente distribuido (mercurial, git, etc.), y la solución, escrita en HTTP / ReST, parece un poco similar.
Suponiendo que tienes dos usuarios, Alice y Bob, ambos trabajando en /articles/lunch
. (para mayor claridad, la respuesta está en negrita)
Primero, Alicia crea el artículo.
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
El servidor no creó un recurso, porque no había una "versión" adjunta a la solicitud, (asumiendo un identificador de /articles/{id}/{version}
. Para realizar la creación, Alice fue redirigida a la url del artículo / versión que ' El agente de usuario de Alice volverá a aplicar la solicitud en la nueva dirección.
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
Y ahora el artículo ha sido creado. A continuación, Bob mira el artículo:
GET /articles/lunch HTTP/1.1
Host: example.com
Authorization: Basic Ym9iOnBhc3N3b3Jk
301 Moved Permanently
Location: /articles/lunch/1
Bob mira allí:
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?
Él decide agregar su propio cambio.
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
Al igual que con Alice, Bob se redirige a donde creará una nueva versión.
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 le gustaría agregar a su propio artículo:
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.
En lugar de ser redirigido como de costumbre, se devuelve un código de estado diferente al cliente, 409
, que le dice a Alice que la versión de la que estaba intentando derivar ya se ha ramificado. Los nuevos recursos se crearon de todos modos (como se muestra en el encabezado Location
), y las diferencias entre los dos se incluyeron en el cuerpo de la respuesta. Alice ahora sabe que la solicitud que acaba de hacer debe fusionarse de alguna manera.
Todo este redireccionamiento está relacionado con la semántica de PUT
, que requiere que se creen nuevos recursos exactamente donde la línea de solicitud solicita. esto también podría guardar un ciclo de solicitud usando POST
en su lugar, pero entonces el número de versión tendría que estar codificado en la solicitud por alguna otra magia, lo que me pareció menos obvio para los propósitos de ilustración, pero probablemente todavía se prefiera en una API real para minimizar los ciclos de solicitud / respuesta.