Actualización masiva: devolver todos los resultados o solo fallos

7

Estoy desarrollando una API que realiza una actualización masiva de una gran cantidad de elementos en una sola llamada. Este código constará de un punto final REST y el código de biblioteca interno al que llama.

Hay algunas razones por las que la actualización de un elemento específico puede fallar (por ejemplo, el elemento se ha eliminado). La pregunta que estoy debatiendo es cómo devolver el resultado a la persona que llama.

Me inclino por devolver una colección que contenga solo los elementos con fallas, pero podría ver escenarios en los que sería útil devolver el resultado para todos ellos.

En cualquier caso, la respuesta contendría una colección de objetos como este:

class UpdateResponse
{
    int ItemId;
    ResultType Result;
}

Donde ResultType es una enumeración que describe el resultado de la actualización.

¿Hay alguna razón convincente para elegir una estrategia sobre la otra (devolver todas las fallas en comparación con la devolución)?

    
pregunta Jack A. 03.02.2016 - 13:43

5 respuestas

4

Tienes dos opciones. Ya sea para usar el 200 OK o el 207 Multi-Status .

No recomendaría usar este último, ya que es un código de estado de WebDav (WebDav es una extensión de HTTP) que lo obliga a responder con un documento XML. Aunque le permite usar múltiples códigos de estado en su respuesta.

Mi preferencia iría al 200 OK porque básicamente significa: "sí, tu solicitud se ha completado". Ese es tu caso.

La segunda pregunta es una opción entre: "su solicitud se ha completado: aquí hay un resumen" o "su solicitud se ha completado: esto es lo que no funciona". La verdadera pregunta es: ¿el cliente debe saber que un artículo se ha actualizado correctamente?

  • Sí: proporcione todos los resultados.
  • No: proporcionar solo fallos. Se evitará que un cliente analice la respuesta completa con información innecesaria.
respondido por el AilurusFulgens 04.02.2016 - 10:40
1
  

Hay algunas razones por las que la actualización de un elemento específico puede fallar (por ejemplo, el elemento se ha eliminado). La pregunta que estoy debatiendo es cómo devolver el resultado a la persona que llama.

Touchstone: ¿cómo lo harías como página web?

Presumiblemente, el usuario comenzaría a mirar una página web, con un formulario que le permitiría describir la tarea: los trabajos en el lote. El botón Enviar enviaría el formulario al recurso identificado por form.action. La respuesta sería otra página html.

Expresado en términos REST, el estado inicial de la aplicación se describiría mediante un documento de hipermedia (la página html) con controles de hipermedia (enlaces / formularios). La aplicación representaría los controles basados en su interpretación del tipo de medio (parámetros de formulario). El usuario configuraría y elegiría qué control activar, qué enviaría un mensaje a un recurso en el servidor, que respondería con otro documento de hipermedia que describa el siguiente estado de la aplicación.

Eso es RMM nivel 3, de todos modos. Depende de usted cuánto desea impulsar hacia esa meta, pero me parece más fácil trabajar al revés de "correcto" a "práctico".

  

Me inclino por devolver una colección que contenga solo los elementos con fallas, pero podría ver escenarios en los que sería útil devolver el resultado para todos ellos.

De nuevo, ¿cómo manejarías esto con las páginas web? Es probable que devuelva el html que sea más útil para el caso común, e incluya un enlace a otros recursos que describan el resultado con una granularidad diferente. Eso te ayudará a lograrlo en la versión 1, pero eventualmente descubrirás que algunos usuarios siempre prefieren la representación secundaria. Así que configurará un nuevo recurso que acepta el lote de trabajos y devuelve la representación secundaria (probablemente con un enlace al primero). Su página web inicial tendría dos enlaces, cada uno de los cuales publicará el mismo trabajo por lotes en un recurso diferente, de modo que el usuario pueda expresar su preferencia por una representación de inmediato, eliminando el clic adicional.

Puedes usar el mismo truco con otras representaciones. En RMM-3, sus documentos tendrían controles de hipermedia para conectar la aplicación a otras representaciones de los resultados, pero en RMM-2 puede obtener con dos recursos diferentes que aceptan el mismo lote de trabajos y producen informes diferentes.

El punto clave aquí es que es un problema fácil de abordar más adelante, simplemente agrega otro recurso que haga el mismo trabajo.

Suponiendo que está utilizando HTTP para transferir sus documentos de un lado a otro, es muy probable que el código de estado correcto sea 201 (creado). No está describiendo el resultado del trabajo en el back-end, está describiendo lo que está sucediendo con los recursos. Aquí, presumiblemente, está tomando la solicitud que envió el trabajo a "alguna representación de los resultados". A menos que tenga tiempo para viajar, es probable que el informe de los resultados no existiera antes de que la solicitud llegara a su servidor, por lo que es natural que esté creando un nuevo recurso (el documento que describe los resultados).

Por lo que puedo ver, no es particularmente crítico para hacer esto bien; devolver un 200 (OK) en su lugar probablemente está bien. Le llamo la atención, porque creo que pensar en el documento ayuda a superar el bloqueo mental de confundir el "recurso" con la "cosa que realmente hace el trabajo".

Consulte: REST en la práctica por Jim Webber.

    
respondido por el VoiceOfUnreason 05.02.2016 - 05:22
0

Es probable que tenga dificultades para ajustar este tipo de solicitud en un enfoque REST, ya que está fundamentalmente dirigido a acceder a un solo recurso.

Dicho esto, para la respuesta, simplemente devolvería 200 OK si algunas fallas no significan una falla global, y 409 Conflict si lo hace. Puede poner lo que quiera en el cuerpo de estas respuestas, por lo que es mejor ser exhaustivo y mencionar los éxitos y los fracasos.

    
respondido por el guillaume31 03.02.2016 - 17:14
0

Argumentaría que debería devolver un identificador de lote de algún tipo y proporcionar otro punto final al que el usuario pueda llamar para obtener la información que desee sobre el lote. Esto sería especialmente útil si el lote contiene una gran cantidad de elementos que demoran un tiempo en procesarse, ya que le permitiría devolver una respuesta 202 Accepted con el ID del lote de inmediato (por lo que la solicitud no caduca). luego devolver los datos en una llamada posterior. Por lo tanto, terminaría aceptando un POST a /api/batch para enviar el lote, devolvería un 202 con un ID de lote, y luego brindaría al usuario la posibilidad de enviar un GET a /api/batch/:id/failures para obtener los registros fallidos, o /api/batch/:id/processed para obtener todos los exitosos, etc.

    
respondido por el TMN 03.02.2016 - 17:27
0

Sé cómo lo haría en un servicio WCF.

class UpdateResponse
{
    int ItemId;
    ResultType Result;
}

Class Result
{
   Status   //"success"     = ALL items were successfully updated
            //"fail"    = At least 1 item in list failed

           //If status = "sucess" then ItemResponse will be empty
           //If status = "fail", this will contain an entry for EVERY 
           //item that was in the original request 
   List<UpdateResponse> ItemUpdateResponse          
}

El motivo para tener todos los elementos de la lista devuelta en cualquier error Es para que si el usuario de su API quiere relacionar su lista original. con la lista devuelta, pueden hacerlo usando la posición ordinal.

    
respondido por el user2669338 05.02.2016 - 13:06

Lea otras preguntas en las etiquetas