How to use the response from a ServiceCallout as the response for the Proxy?

Not applicable

Hello,

I am implementing something on Edge Proxy. I am working only within "target endpoint". First request is assign message policy and whatever response comes, I parse particular value in response with help of Extract variable policy. Then I use 2 values from extract variable policy and pass it into service callout policy inside <Payload>. and I am changing <Path> here because my target url and service callout policy's path is different. I am providing correct url too in service call out policy in <Target> tag. Now my question is, I need final response is display from service callout policy not the first request sent from assign message policy.

Please guide me how can I use <response> tag of service callout policy too.

Thank you. 🙂

2 13 12.4K
13 REPLIES 13

Dear @Dhwani Trivedi ,

You need to use one more Assign Message policy after your service callout to override response send to client using variable collected in service callout response tag.

Thank you @Anil Sagar .

Do you have any example on this either in documentation or http://stackoverflow.com/questions/tagged/apigee ?

Also, I am bit confuse in <Response> tag in service callout policy. Where and where it should helpful? I mean how I can use that and where I can use it? Please guid me.

Thank you.

@Dhwani Trivedi

, Check examples and documentation here. Basically, Response from service callout is stored in variable mentioned in response tag.

<ServiceCallout name="GeoCodeClient">
    <Request clearPayload="false" variable="GeocodingRequest"/>
    <Response>GeocodingResponse</Response>
    <Timeout>30000</Timeout>
    <HTTPTargetConnection>
      <URL>http://maps.googleapis.com/maps/api/geocode/json</URL>
    </HTTPTargetConnection>
</ServiceCallout>

Response from Google API is stored in , GeocodingResponse variable that you can use in further policies after service callout policy.

One more example here that does mashup of policies.

Thank you @Anil Sagar .

I used this in my project this and then after service callout policy I used Extract Variable Policy to display response but, I am getting "Paused" in trace before extract variable policy run. and get response of first request done through assign message policy.

As you suggested me in previous reply, I should use assign message policy after service call out policy right? what make a difference that tI can get final response display is from service call out policy? Could you help me out to understand please?

Thank you.

After the ServiceCallout, you have the response in a context variable. you then need to embed THAT response into the proxy response. Do that with another AssignMessage policy.

<AssignMessage name='AssignMessage-CalloutResponse'>
  <AssignTo createNew='false' transport='http' type='response'/>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <Set>
    <Payload contentType='application/json' variablePrefix='%' variableSuffix='#'>%GeocodingResponse#</Payload>
    <StatusCode>200</StatusCode>
    <ReasonPhrase>OK</ReasonPhrase>
    <Headers>
      <Header name='xxx'>whatever you like</Header>
       ....
    </Headers>
    ...
  </Set>
</AssignMessage>

Hello @Anil Sagar & @Dino

As you guided me, I added Assign message policy after service call out policy but, I am getting this below error in trace. This error come when service call out police comes in the picture.

Please see the attachment and guide me if you know.

Thank you.

adas
New Member
@Dhwani Trivedi

I didn't have access to your proxy source code, so I can't really tell what's going on there. Looks like there's an EOF exception in your service callout. Probably something is not configured correctly in your service callout policy.

I created a simple proxy with a service callout and javascript which does the same thing as above. You can use this for your use-case of populating the service callout response and proxy response. Please find the attachment.

Thank you @arghya das. I saw your code. I did something like that but, in my service callout policy , I need to send<Request><Set> <Payload>""xyz"} </Payload></Set><Request> as a request json body. And I am providing <Response>newFinalResponse</Response>so, I can extract values using extract variable policy.

adas
New Member

@Dhwani Trivedi Best practices for service callouts would be to set the request payload, headers etc. in an AssignMessage. Once you have the response in a variable you can do extract variable or any other operations you want. Looking at your trace session, I was not sure if you were using any assign message policy to set the service callout request payload. Here's an example:

<AssignMessage name="AssignServiceCalloutPayload" enabled="true">
<AssignTo type="request">sc_request</AssignTo>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<Copy source="request">
    <Path>false</Path>
  </Copy>
<Remove>
</Remove>
<Add>
      <Headers>
        <Header name="verb">POST</Header>
    </Headers>
    <QueryParams>
        <QueryParam name="test">foobar</QueryParam>
    </QueryParams>
</Add>
<Set>
    <Payload>
        <![CDATA[<s:Envelope
         xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
         xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
         xmlns:xsd="http://www.w3.org/1999/XMLSchema">
        <s:Header>
         <m:transaction xmlns:m="soap-transaction" s:mustUnderstand="true">
          <transactionID>00511</transactionID>
         </m:transaction>
        </s:Header>
         <s:Body>
          <m:sayHello xmlns:m='urn:XML_module'>
          <!-- XML Data Structure begins -->
                <DATA_STRUCTURE>
                <DATA name="dataname" value="Hello World!"/>
                </DATA_STRUCTURE>
          <!-- XML Data Structure ends -->
          </m:sayHello>
         </s:Body>
        </s:Envelope>]]>
    </Payload>
    <Verb>GET</Verb>
</Set>
  <AssignVariable>
        <Name>target.copy.pathsuffix</Name>
    <Value>false</Value>
    </AssignVariable>
</AssignMessage>

Thank you @arghya das. This is helpful but, I stuck, how can I change my uri path not whole url? and also, this policy comes in the picture at target endpoint response area as a new request and I am trying to display final response is the response that I get from this either Assign Message policy or service callout policy at response target endpoint side.

Please guide me.

I am sorry, I don't think I understood your last comment. If I can take a look at your proxy, maybe I can give some guidance.

If I understood your requirement correctly, here's what you want:

- make a service callout with a POST body to a given URL

- get the response, extract certain elements of the response using a extract variable

- you also want to send the service callout response call to the caller as a proxy response

Have I captured your requirements, correctly. If yes, then the proxy that I attached earlier, does exactly that, except that it doesn't have an assign message policy to set the service callout request object (the policy I posted above). If there's anything that you are looking to do beyond this, it would be helpful if you can attach your proxy here so that I can take a look.

@arghya das I have used the same javascript code which you attached in the proxy for copying service callout response to the caller as a proxy response but I am getting following javascript error related to the "content" variabale in context.proxyResponse.content = JSON.stringify(originalResponse);

{"fault":{"faultstring":"Execution of PopulateGeocodeResponse failed with error: Javascript runtime error: \"TypeError: Cannot set property \"content\" of undefined to \"{\n \"results\": [\n {\n \"address_components\": [\n {\n \"long_name\": \"123\",\n \"short_name\": \"123\",\n \"types\": [\n \"street_number\"\n ]\n },\n {\n \"long_name\": \"Main Street\",\n \"short_name\": \"Main St\",\n \"types\": [\n \"route\"\n ]\n },\n {\n \"long_name\": \"Rexford\",\n \"short_name\": \"Rexford\",\n \"types\": [\n \"locality\",\n \"political\"\n ]\n },\n {\n \"long_name\": \"Clifton Park\",\n \"short_name\": \"Clifton Park\",\n \"types\": [\n \"administrative_area_level_3\",\n \"political\"\n ]\n },\n {\n \"long_name\": \"Saratoga County\",\n \"short_name\": \"Saratoga County\",\n \"types\": [\n \"administrative_area_level_2\",\n \"political\"\n ]\n },\n {\n \"long_name\": \"New York\",\n \"short_name\": \"NY\",\n \"types\": [\n \"administrative_area_level_1\",\n \"political\"\n ]\n },\n {\n \"long_name\": \"United States\",\n \"short_name\": \"US\",\n \"types\": [\n \"country\",\n \"political\"\n ]\n },\n {\n \"long_name\": \"12148\",\n \"short_name\": \"12148\",\n \"types\": [\n \"postal_code\"\n ]\n },\n {\n \"long_name\": \"1132\",\n \"short_name\": \"1132\",\n \"types\": [\n \"postal_code_suffix\"\n ]\n }\n ],\n \"formatted_address\": \"123 Main St, Rexford, NY 12148, USA\",\n \"geometry\": {\n \"bounds\": {\n \"northeast\": {\n \"lat\": 42.8523593,\n \"lng\": -73.88743330000001\n },\n \"southwest\": {\n \"lat\": 42.8523465,\n \"lng\": -73.8874402\n }\n },\n \"location\": {\n \"lat\": 42.8523593,\n \"lng\": -73.88743330000001\n },\n \"location_type\": \"RANGE_INTERPOLATED\",\n \"viewport\": {\n \"northeast\": {\n \"lat\": 42.8537018802915,\n \"lng\": -73.8860877697085\n },\n \"southwest\": {\n \"lat\": 42.8510039197085,\n \"lng\": -73.88878573029152\n }\n }\n },\n \"partial_match\": true,\n \"place_id\": \"EiMxMjMgTWFpbiBTdCwgUmV4Zm9yZCwgTlkgMTIxNDgsIFVTQQ\",\n \"types\": [\n \"street_address\"\n ]\n }\n ],\n \"status\": \"OK\"\n}\" (geocoderesponse_js#2). at line 2 \"","detail":{"errorcode":"steps.javascript.ScriptExecutionFailed"}}}

Not applicable

@raghavendra: Hi Arghya Das I have replicated the code given in 'service-callout-rev2-2015-09-10.zip' ,but I am getting null response.I have created everything as suggested in the example.

Here are the details .

Proxy.xml:ServiceCalloutwithJavascript

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <APIProxy revision="1" name="ServiceCalloutwithJavascript"> <Basepaths>/servicecalloutwithjavascript</Basepaths> <ConfigurationVersion majorVersion="4" minorVersion="0"/> <CreatedAt>1477461021716</CreatedAt> <CreatedBy>nvraghavendra254@gmail.com</CreatedBy> <Description/> <DisplayName>ServiceCalloutwithJavascript</DisplayName> <LastModifiedAt>1477467445649</LastModifiedAt> <LastModifiedBy>nvraghavendra254@gmail.com</LastModifiedBy> <Policies> <Policy>Assign-Message-1</Policy> <Policy>GeoCodeClient</Policy> <Policy>PopulateResponse</Policy> </Policies> <ProxyEndpoints> <ProxyEndpoint>default</ProxyEndpoint> </ProxyEndpoints> <Resources> <Resource>jsc://PopulateResponse.js</Resource> </Resources> <Spec/> <TargetServers/> <TargetEndpoints/> <validate>false</validate> </APIProxy>

Assign message-1:Assign-Message-1

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <AssignMessage async="false" continueOnError="false" enabled="true" name="Assign-Message-1"> <DisplayName>Assign Message-1</DisplayName> <Properties/> <Copy source="response"> <Headers/> <QueryParams/> <FormParams/> <Payload/> <Verb/> <StatusCode/> <ReasonPhrase/> <Path/> </Copy> <Set> <Headers/> <QueryParams/> <FormParams/> <!-- <Verb>GET</Verb> --> <Path/> <Payload contentType="application/json"/> </Set> <AssignVariable> <Name>name</Name> <Value/> <Ref/> </AssignVariable> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <AssignTo createNew="false" transport="http" type="request"/> </AssignMessage>

Service callout:GeoCodeClient

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ServiceCallout name="GeoCodeClient"> <DisplayName>GeoCodeClient</DisplayName> <Properties/> <Request clearPayload="true" variable="GeocodingRequest"> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> </Request> <Response>>GeocodingResponse</Response> <Timeout>30000</Timeout> <HTTPTargetConnection> <Properties/> <URL>http://services.groupkt.com/country/get/iso2code/IN</URL> </HTTPTargetConnection> </ServiceCallout>

Javascript: PopulateResponse

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="PopulateResponse"> <DisplayName>PopulateResponse</DisplayName> <Properties/> <ResourceURL>jsc://PopulateResponse.js</ResourceURL> </Javascript>

javascript:

var originalResponse = JSON.parse(context.getVariable('GeocodingResponse.content')); context.proxyResponse.content = JSON.stringify(originalResponse);

Note: I have used no endpoint proxypoint ,where I dont define any target endpoint.

Please help me on this .