rest - codigos de respuesta api
¿Buscar o crear expresiones idiomáticas en el diseño de la API REST? (4)
digamos que tenemos un recurso de ''usuario'' con una restricción única en ''nombre''. ¿Cómo diseñaría una API REST para manejar un caso de uso de buscar o crear (por nombre)? Veo las siguientes opciones:
Opción 1: múltiples solicitudes
cliente:
POST /user
{"name":"bob"}
servidor:
HTTP 409 //or something else
cliente:
GET /user?name=bob
servidor:
HTTP 200 //returns existing user
Opción 2: una solicitud, dos códigos de respuesta
cliente:
POST /user
{"name":"bob"}
servidor:
HTTP 200 //returns existing user
(En caso de que el usuario esté realmente creado, devuelva HTTP 201)
Opción 3: errores de solicitud pero los datos de respuesta contienen una entidad en conflicto
cliente:
POST /user
{"name":"bob"}
servidor:
HTTP 409 //as in option1, since no CREATE took place
{"id": 1, "name":"bob"} //existing user returned
Creo que la forma REST "correcta" de hacer esto sería:
GET /user?name=bob
200: entity contains user
404: entity does not exist, so
POST /user { "name" : "bob" }
303: GET /user?name=bob
200: entity contains user
También soy un gran fanático del patrón Post-Redirect-Get, que implicaría que el servidor envíe una redirección al cliente con el uri del usuario recién creado. Su respuesta en el caso POST tendría entonces la entidad en su cuerpo con un código de estado de 200.
Esto significa 1 o 3 viajes de ida y vuelta al servidor. La gran ventaja de PRG es proteger al cliente para que no se vuelva a enviar cuando se produce una recarga de la página, pero debe leer más sobre esto para decidir si es adecuado para usted.
Si esto es demasiado con el servidor, puede hacer la opción 2. Esto no es estrictamente RESTful por mi lectura de https://tools.ietf.org/html/rfc2616#section-9.5 :
La acción realizada por el método POST puede no resultar en un recurso que puede ser identificado por un URI. En este caso, 200 (OK) o 204 (Sin contenido) es el estado de respuesta adecuado, dependiendo de si la respuesta incluye o no una entidad que describe el resultado.
Si está de acuerdo con desviarse del estándar y le preocupan los viajes de ida y vuelta, entonces la Opción 2 es razonable.
Creo que una solicitud GET que:
- devuelve un registro existente; o
- crea un nuevo registro y lo devuelve
es el enfoque más eficiente como se explica en mi respuesta aquí: Crear registro / perfil de usuario para iniciar sesión por primera vez
Es irrelevante que el servidor necesite crear el registro antes de devolverlo en la respuesta, tal como lo explicaron @Cormac Mulhall y @Blake Mitchell en REST. Referencia perezosa ¿Crear GET o POST?
Esto también se explica en la Sección 9.1.1 de la especificación HTTP :
Naturalmente, no es posible garantizar que el servidor no genere efectos secundarios como resultado de realizar una solicitud GET; de hecho, algunos recursos dinámicos consideran que una característica. La distinción importante aquí es que el usuario no solicitó los efectos secundarios , por lo tanto, no puede ser responsabilizado por ellos.
Estoy usando una versión de la opción 2 . Devuelvo 201 cuando se crea el recurso y 303 ("ver otro") cuando simplemente se recupera. Elegí hacer esto, en parte, porque get_or_create no parece ser un lenguaje REST común, y 303 es un código de respuesta ligeramente inusual.
Iría con la Opción 2 por dos razones:
Primero, el código de respuesta HTTP, 2xx (por ejemplo, 200 nd 201) se refiere a una operación exitosa a diferencia de 4xx. Por lo tanto, en ambos casos, cuando se produce o se produce, tiene una operación exitosa.
En segundo lugar, la Opción 1 duplica la cantidad de solicitudes al servidor, lo que puede ser un golpe de rendimiento para una carga pesada.