Hello All,
I am using the <ServiceCallout> to call another REST service in one of my flows. In the policy, I have <Response>callAdrumApiCalloutResponse</Response> to store the response from the callout, and that works just fine for the content. I have a requirement to be able to store the response headers from the <ServiceCallout> and the cannot find an easy way to get this through the JavaScript notation, it returns null
In Javascript, this works fine:
var content = JSON.stringify(context.getVariable('callAdrumApiCalloutResponse.content')); print ("callAdrumApiCalloutResponse.content: " + content);
This returns **null** when I try to get the headers:
var headers = JSON.stringify(context.getVariable('callAdrumApiCalloutResponse.headers')); print ("callAdrumApiCalloutResponse.headers: " + headers);
I am unsure if I am missing something, but if we're saving the entire response from the <ServiceCallout>, shouldn't the headers be somewhere in this object as well (assuming "callAdrumApiCalloutResponse.headers")? I am able to get the headers if I use an <ExtractVariables> policy right after the <ServiceCallout>, but it is a horrible workaround considering how much juggling I need to do to get it into the original header structure to be stored.
As any request we do with "httpClient" give us myResponse.getResponse().headers, myResponse.getResponse().content and myResponse.getResponse().status -- why wouldn't the response for the <ServiceCallout> have a similar notation to get the headers? Is it possible this is a bug and someone forgot to attach the headers to the resultant response object generated from the <ServiceCallout>?
TIA, Steve
The headers cannot be accessed in the way you have tried if the call is made via Target Endpoint or Service Callout. Apigee does not set <Message>.headers variable into the context. The following are the different header related variables you can use to extract variables within JS. You can find more information in Variable Reference.
response.header.{header_name} | Scope: Target response
Type: String
Permission: Read/Write Gets or sets the value of a specified HTTP header in the response |
response.header.{header_name}.values | Scope: Target response
Type: Collection
Permission: Read All the values of a specified HTTP header in response |
response.header.{header_name}.values.count | Scope: Target response
Type: Integer
Permission: Read Count of all the values of the specified HTTP header in response |
response.headers.count | Scope: Target response
Type: Integer
Permission: Read Count of all the headers in the response |
response.headers.names | Scope: Target response
Type: Collection
Permission: Read The names of all the headers in the response |
Thanks,
Abhishek
That is incorrect - the right way is to "name" the calloutResponse something other than "response", and then get the headers per your code as:
calloutResponse.headers.names
The reason you are missing a header is because the javascript has a bug - headerNames comes back as a string in this format [x, y, z, ... ]. The brackets are part of the string, so you have to substring them out out, otherwise the first and last header you are trying to use is "[x" and "z]", which is not a valid header name. Once you remove the brackets, it should work fine
See similar question asked here with accepted solution. Please let us know if you have any queries. I have tested same and working as expected.
var headerNames = context.getVariable("response.headers.names") + ""; headerNames.split(", ").sort().forEach(function(headerName) { if (headerName) print(headerName+":"+context.getVariable("response.header."+headerName)); });
That is incorrect - the right way is to "name" the calloutResponse something other than "response", and then get the headers per your code as:
calloutResponse.headers.names
The reason you are missing a header is because the javascript has a bug - headerNames comes back as a string in this format [x, y, z, ... ]. The brackets are part of the string, so you have to substring them out out, otherwise the first and last header you are trying to use is "[x" and "z]", which is not a valid header name. Once you remove the brackets, it should work fine