necesitamos enviar todos los datos del artículo a la API para su actualización y no se pudo implementar el trabajo multiusuario. Por ejemplo, el editor podría enviar datos 5 segundos más antiguos y sobrescribir la corrección que otro periodista acaba de hacer hace 2 segundos y no hay forma de que pueda explicar esto a los clientes, ya que aquellos que publican un artículo no están de ninguna manera conectados con la actualización del contenido.
Este tipo de cosas es un desafío, no importa lo que haga, es un problema muy similar al control de fuente distribuida (mercurial, git, etc.), y la solución, escrita en HTTP / ReST, se ve un poco similar.
Supongamos que tienes dos usuarios, Alice y Bob, ambos trabajando /articles/lunch
. (para mayor claridad, la respuesta está en negrita)
Primero, Alice 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 (suponiendo un identificador de /articles/{id}/{version}
. Para realizar la creación, Alice fue redirigida a la url del artículo / versión que creará. Usuario de Alice El agente 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?
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 es redirigido 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 de la forma normal, se devuelve un código de estado diferente al cliente 409
, que le dice a Alice que la versión de la que estaba tratando de ramificarse ya se ha ramificado. Los nuevos recursos se crearon de todos modos (como se muestra en el Location
encabezado), y las diferencias entre los dos se incluyeron en el cuerpo de respuesta. Alice ahora sabe que la solicitud que acaba de hacer debe fusionarse de alguna manera.
Toda esta redirección está relacionada con la semántica de PUT
, que requiere que se creen nuevos recursos exactamente donde lo solicita la línea de solicitud. esto también podría ahorrar un ciclo de solicitud utilizando POST
, pero luego 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 fines ilustrativos, pero probablemente aún sería preferido en una API real para minimizar los ciclos de solicitud / respuesta.
api/article?action=publish
? Los parámetros de consulta están destinados a casos en los que el estado del recurso depende del 'algoritmo' (o acción) que usted menciona. Por ejemplo,api/articles?sort=asc
es válido