Service Mashup

El Service Mashup es un agrupador de Service Callouts configurados como asíncronos. Al permitir que las llamadas externas se ejecuten en paralelo, Service Mashup proporciona una ventaja sobre el tiempo de ejecución de las llamadas a la API centralizadora al aprovechar mejor el tiempo, como se demuestra en el abajo.

Configuración del interceptor

La imagen a continuación presenta las informaciones para configurar el interceptor:

mediation service mashup
  • Services callouts to wait: lista todos los Service Callouts asíncronos disponibles que no sean Fire and Forget y que no están contenidos en otro Service Mashup.

  • Timeout (ms): determina el tiempo de espera en milisegundos. Cuando el valor no es configurado, consideramos el mayor timeout entre los Service Callouts seleccionados.

  • Abort if any request fails: aborta la petición si alguno de los Service Callouts seleccionados falla. Se caracteriza una falla cuando el status code de la respuesta es diferente del esperado.

Funcionamiento

Para mostrar cómo funciona el Service Mashup, consideremos el siguiente caso:

Una organización, la LSA (Lost Souls' Alliance), desarrollará una API central, LSA Communication, que podrá enviar, vía POST, el mismo mensaje (o comando) a personas dentro y fuera de la organización. Esta API estará registrada bajo el dominio lsa.org.mx.

El mensaje, enviado como JSON en el cuerpo de la llamada, será:

{
  "message": "Join or Die! Viva la revolución!",
  "author": "Salvador Limones"
}

El caso de la comunicación interna se abordó en el funcionamiento de Internal API Call. El caso externo, en el funcionamiento de Service Callout. Ahora vamos a combinar estas dos comunicaciones en una sola llamada.

Las siguientes imágenes muestran, respectivamente, la secuencia de interceptores en el flujo de la API y la configuración utilizada en el interceptor Service Mashup, que espera las respuestas de los dos interceptores Service Callout para continuar el flujo:

mediation service mashup flow
mediation service mashup config

La configuración utilizada para el interceptor Internal API Call es la misma que se describe en su funcionamiento. Las utilizadas para los dos interceptores Service Callout son también las mismas que las descritas en su funcionamiento, excepto que el campo Asynchronous ha sido seleccionado y por lo tanto el uso de Service Mashup es ahora necesario.

A diferencia del caso en el que los dos interceptores Service Callout estaban configurados para actuar de forma sincrónica, ahora ambos se ejecutan en paralelo. Para aprovechar el tiempo de espera, el Internal API Call se llama después de ellos, ejecutándose mientras las otras dos llamadas están en curso.

Al final de la ejecución de Internal API Call, la respuesta devuelta, que es un objeto de tipo ApiResponse, se almacena en las variables del contexto. A continuación, el Service Mashup espera las respuestas devueltas por los dos interceptores Service Callout, que son objetos de tipo RESTResponse, y también almacena estas respuestas en las variables del contexto. Para recuperar todas las respuestas, es necesario crear un custom interceptor que acceda a $call.contextVariables.get(“Variable Name”).

A continuación se muestra el código para el custom JavaScript interceptor que se utilizará para capturar todas las respuestas e incluir los cuerpos y los estados en la respuesta final:

// Captura la respuesta de Internal API Call
var respRadio = $call.contextVariables.get('radioMessages');

// Captura las respuestas de los Service Callouts
var respManny = $call.contextVariables.get('mannyMessage');
var respMeche = $call.contextVariables.get('mecheMessage');

// Crea un objeto ApiResponse para esta llamada
$call.response = new com.sensedia.interceptor.externaljar.dto.ApiResponse();
$call.response.addHeader('Content-Type', 'application/json');

// Plantilla JSON para los mensajes devueltos
var respBody = JSON.parse(`
    {"radio": {"status": 0, "body": {}},
     "pigeonManny": {"status": 0, "body": {}},
     "pigeonMeche": {"status": 0, "body": {}}}
`);

// El estado devuelto es Object, no Number
var statusRadio = respRadio.getStatus();
var statusManny = respManny.getStatus();
var statusMeche = respMeche.getStatus();

// Se llama al método intValue para obtener un objeto Number
respBody.radio.status = statusRadio.intValue();
respBody.pigeonManny.status = statusManny.intValue();
respBody.pigeonMeche.status = statusMeche.intValue();

// Se inserta un cuerpo sólo si se devuelve un estado 200
// Obtene el cuerpo de un ApiResponse
if (statusRadio == 200){
    respBody.radio.body = JSON.parse(respRadio.getBody().getString("UTF-8"));
}

// Obtene el cuerpo de un RESTResponse
if (statusManny == 200){
    respBody.pigeonManny.body = JSON.parse(respManny.getResponseText());
}

if (statusMeche == 200){
    respBody.pigeonMeche.body = JSON.parse(respMeche.getResponseText());
}

// Inserta el cuerpo modificado en el ApiResponse
$call.response.getBody().setString(JSON.stringify(respBody), "UTF-8");

// Establece el estado de retorno como 200
$call.response.setStatus(200);

Finalmente, el cuerpo de la respuesta de la llamada POST al recurso all-messages de LSA Communication será:

{
  "radio": {
    "status": 200,
    "body": {
      "messages": [
        {
          "message": "I've already joined, Sal, a year ago. Is this just a test message?",
          "author": "Eva"
        }
      ]
    }
  },
  "pigeonManny": {
    "status": 200,
    "body": {
      "message": "I'm already dead...",
      "author": "Manuel Calavera"
    }
  },
  "pigeonMeche": {
    "status": 200,
    "body": {
      "message": "Only if it has cars, as I was given one purpose, one skill, one desire: to DRIVE!",
      "author": "Glottis"
    }
  }
}
Thanks for your feedback!
EDIT

Share your suggestions with us!
Click here and then [+ Submit idea]