How to create an API by mashup the response with 2 or more calls in the backend services

If you like mix some fields on the front-end by response content only once.

So these fields could are obtained from 2 or more different existing back-end services.

To reduce response time and complexity on the UI side, you can think of creating an API that will call these backend services in parallel (using the JAVASCRIPT policy) and mash up the response and return it to the front end.

You could use the ServiceCallout policy to call the backend, but I found it slower and you have to add more policies like (extract variables, assign messages) from a single API and perform the response mashup on the API.

Let's go,

- Create a API Proxy;

- Add a police (Javascript);

- Put the resource by <ResourceURL>

- Add a resource JAVASCRIPT and File Type New Javascript:

var input_push = JSON.parse(context.getVariable("request.content"));
var pushFieldidDevice = input_push.idDevice; //get the field do json request

// create the first variable json with the field received
var msgpush = '';
    msgpush =
            {
                "sandbox": true,
                 "apns_tokens": [pushFieldidDevice]
            };
    
    
//prepare the first target url 
var urlName = (context.getVariable("environment.name")=='prod') ?  'app.example.com' : 'sandbox.example.com';


    var urlTargetImport = 'https://' + urlName + '/id/v1:batchImport';
    
    var extChild = new Request(urlTargetImport, 'POST', {'Content-Type':'application/json', 'Authorization': 'key=1234AAA1'}, JSON.stringify(msgpush));
    var getChild = httpClient.send(extChild);
    
    getChild.waitForComplete();
    
    
    if (!getWcsChild.isSuccess()) {
        //will be used in the preflow case error
        context.setVariable("triggerError", "true");
        context.setVariable("erroWrk", 'Erro na chamada do servico de Geracao de Token');
        
    } else {
        
        var responseObjPush = getChild.getResponse().content;
        print(responseObjPush); //debug
        var input_data = JSON.parse(responseObjPush);
        var arrayFieldItens = input_data.results;
        for (var i=0;i<arrayFieldItens.length;i++){


            var currentElement=arrayFieldItens[i];
            var xmlString = '';
            for (var key in currentElement) { 


                if (key == "registration_token") {
                    xmlString =  currentElement[key];
                }
            }
        }


    }
    



//prepare the second target url with path and querystring 

    var urlTargetPush = 'https://' + urlName + '/info/' + xmlString + '?details=true';
    
    context.setVariable("requestURL",urlTargetPush); //debug
    


    var extPushAdd = new Request(urlTargetPush, 'GET', {'Authorization': 'key=1234AAA'});
    var getPushAdd = httpClient.send(extPushAdd);
    
    getPushAdd.waitForComplete();
    
    
    if (!getPushAdd.isSuccess()) {
        context.setVariable("triggerError", "true");
        context.setVariable("erroWrk", 'Erro na chamada do servico de consulta de topico');
        
    } else {
        
        var responseObjChild = getPushAdd.getResponse().content;
        var trataErro = String(responseObjChild);
        print(trataErro); //debug
        if (trataErro.indexOf("Error") >= 0){
            context.setVariable("triggerError", "true");
            context.setVariable("erroWrk", 'Erro encontrado no retorno da consulta');
        }
        else{
            //var respostaJS = JSON.parse(responseObjChild);
            response.headers['Content-Type'] = 'application/json';
            context.setVariable("response.content", JSON.stringify(responseObjChild));  
        }
    }

- Add a police (Raise Fault) to return the message error and put <FaultResponse> tag ;

<Payload contentType="application/json">{

              "error" : {

                "code" : 400,

                "message" : "{erroWrk}"

                  }

                }

</Payload>
<StatusCode>400</StatusCode>
<ReasonPhrase>message error field</ReasonPhrase>

- See that the proxy Endpoint the following steps should be placed as below in the sequence <Response> PostFlow

- extracted in the javascript

<PostFlow name="PostFlow">
<Response>   
   <Step>
           <Name>js-extractInput</Name>
   </Step>
   <Step>
           <Condition>(triggerError = "true")</Condition>
           <Name>trataRetornoErroparaFront</Name>
   </Step>
</Response>
<Request/>
</PostFlow>


thanks!!!
Comments
Not applicable

service callout helps to do this. And that looks easy for me.

fabriziorodrigu
New Member

I know and spoken above: you could use the ServiceCallout policy to call the backend, but I found it slower and you have to add more policies like (field extraction, added messages) from a single API and perform the response mashup on the API.

deboraelkin
Staff

Yes, you'd need to add more policies but it'd save quite a few lines of JS code (All the way to 0). Also, with this approach you're losing visibility in Analytics and API Monitoring (eg: what are the individual target latencies?)

fabriziorodrigu
New Member

Of course and thanks, but if put the time before method http and final, see bellow:

var startTime = new Date().getTime();
// method http

var endTime = new Date().getTime(); context.setVariable("time_newCallWorkflowEditData", (endTime - startTime) + ' ms');

Version history
Last update:
‎08-18-2020 07:54 AM
Updated by: