Service Callout

Assim como o Internal API Call, o Service Callout permite invocar uma nova chamada como parte do fluxo original com base nas configurações estabelecidas. A diferença é que, enquanto o Internal API Call se destina a redirecionamentos para APIs que estejam na Plataforma da Sensedia, o Service Callout permite invocar uma chamada externa.

Configurando o interceptor

As imagens e texto abaixo apresentam as informações a serem preenchidas para configurar o interceptor.

mediation service callout screen
mediation service callout body
mediation service callout header
  • Variable name: define o nome do Service Callout, sendo único por fluxo. É através dessa nomenclatura que a resposta da chamada pode ser recuperada de dentro do mapa $call.contextVariables, sendo necessário um custom interceptor para isso, como mostrado abaixo.

  • URL: define a URL que será invocada na requisição externa.

  • Method: define o método HTTP a ser usado na invocação.

  • Expected status: define o status code esperado.

  • Preserve query string: se a opção for marcada, a query string presente na requisição será repassada para a chamada externa.

  • Preserve body: se o campo for marcado, o body contido na requisição será repassado para a chamada externa. O campo será habilitado quando o method for diferente de GET.

  • Body: permite a inserção de um body. O campo será habilitado quando o método for diferente de GET e a opção Preserve body estiver desmarcada;

  • Preserve headers: se marcado, os headers presentes na requisição serão repassados para a chamada externa.

  • Headers: permite a inserção de headers.

mediation service callout asynchronous

O Service Callout tem a capacidade de realizar chamadas assíncronas ou síncronas. Neste último caso, uma chamada síncrona será enviada para a nova URL e o interceptor ficará aguardando o resultado dessa chamada para continuar a execução do fluxo. Para chamadas assíncronas, selecione o campo Asynchronous.

Para capturar a resposta de chamadas assíncronas, é necessário utilizar o interceptor Service Mashup no fluxo.

As chamadas assíncronas podem ser do tipo Fire and Forget ou não, bastando apenas selecionar o campo ou deixá-lo em branco. Com o campo selecionado, o interceptor vai enviar a chamada e esquecê-la. Nesse caso, não haverá nenhum retorno da nova chamada.

Quando não for marcada a opção Fire and Forget, poderá ser configurado um tempo limite (timeout) para a chamada a ser realizada. Essa chamada será realizada de forma paralela e será encerrada caso o tempo limite seja atingido ou algum resultado seja retornado.

mediation service callout abort
  • Abort request if fail: aborta o processo caso a requisição falhe. Caracteriza-se uma falha quando o status code da requisição é diferente do esperado. O campo será habilitado quando a requisição for síncrona.

Códigos de status de erro

Os códigos de status retornados pelo Service Callout quando acontece algum erro, e os motivos para eles, são:

  • 417: caso o status esperado for diferente do status retornado pela chamada.

  • 408: caso a chamada extrapole o tempo limite (timeout).

  • 500: qualquer outro caso diferente dos que foram mencionados.

Funcionamento

Para mostrar o funcionamento do Service Callout, vamos considerar o seguinte caso:

Uma organização, a LSA (Lost Souls' Alliance), irá desenvolver uma API central, a LSA Communication, que será capaz de enviar, via POST, uma mesma mensagem (ou comando) para pessoas de dentro e de fora da organização. Essa API será registrada sob o domínio lsa.org.mx.

A mensagem, enviada como um JSON no body da chamada, será:

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

No caso da comunicação externa, existe uma API exposta, sob o domínio lsa-spies.org.mx e externa à plataforma da Sensedia, que permite o envio da mensagem pelo sistema externo (pigeons). Esse sistema possui dois recursos para isso: pigeons/pigeon-manny e pigeons/pigeon-meche. Para aproveitar essa API, utilizamos o Service Callout.

Como são dois recursos diferentes, serão utilizados dois interceptors de Service Callout. As imagens a seguir mostram, respectivamente, a sequência dos interceptores no fluxo da API e as configurações utilizadas no interceptor que faz a chamada POST para pigeons/pigeon-manny, sendo semelhantes as configurações para pigeons/pigeon-meche:

mediation service callout flow
mediation service callout config

É importante destacar que, por terem sido configurados para atuar de forma síncrona, o segundo interceptor de Service Callout só será executado após o fim da execução do primeiro. Quando o tempo de execução for uma questão relevante, é recomendável usar chamadas assíncronas, como exemplificado no uso do Service Mashup.

A chamada para pigeons/pigeon-manny retorna, com código de status 200, o seguinte body:

{
  "message": "I'm already dead...",
  "author": "Manuel Calavera"
}

Já a chamada para pigeons/pigeon-meche retorna, também com código de status 200, o seguinte body:

{
  "message": "Only if it has cars, as I was given one purpose, one skill, one desire: to DRIVE!",
  "author": "Glottis"
}

Após cada chamada síncrona, o interceptor irá retornar um objeto do tipo RESTResponse que será armazenado nas variáveis de contexto da chamada. Para recuperar a resposta, é necessário criar um custom interceptor que acesse $call.contextVariables.get(“Variable Name”).

Abaixo está o código do custom JavaScript interceptor que será usado para capturar as respostas e incluir os bodies e os status na resposta final:

// Captura as respostas dos Service Callouts
var respManny = $call.contextVariables.get('mannyMessage');
var respMeche = $call.contextVariables.get('mecheMessage');

// Cria um objeto ApiResponse para essa chamada
$call.response = new com.sensedia.interceptor.externaljar.dto.ApiResponse();
$call.response.addHeader('Content-Type', 'application/json');

// Template JSON para as mensagens retornada
var respBody = JSON.parse(`{
    "pigeonManny": {"status": 0, "body": {}},
    "pigeonMeche": {"status": 0, "body": {}}}
`);

// O status retornado é um Object, não um Number
var statusManny = respManny.getStatus();
var statusMeche = respMeche.getStatus();

// O método intValue é chamado para obter um objeto Number
respBody.pigeonManny.status = statusManny.intValue();
respBody.pigeonMeche.status = statusMeche.intValue();

// O body é inserido apenas se o status retornado for 200
if (statusManny == 200){
    respBody.pigeonManny.body = JSON.parse(respManny.getResponseText());
}

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

// Injeta o body modificado na ApiResponse
$call.response.getBody().setString(JSON.stringify(respBody), "UTF-8");

// Define o status de retorno como 200
$call.response.setStatus(200);

Por fim, o body da resposta da chamada POST ao recurso external-messages da LSA Communication será:

{
  "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
How useful was this article to you?