Change and Set the HTTP status code Response

Not applicable

How can i change and set the HTTP status Code ? I want to set HTTP status code based on my backend service response. Though my backend service is failed some reason(Say Ex:Invalid Request) and the backend service returns Service Error code, but Proxy returns default 200 Ok status code which i want to change based on status of backend service. how do i achieve that ? or what is best way to do that?

Solved Solved
1 13 14.2K
1 ACCEPTED SOLUTION

HI @Kumaresan Sithambaram

If there is a difference between the successful response message and an error response message, you can use an extract variable policy and extract the values from the back end response and use a Raise Fault policy to raise an error with an appropriate http code when that variable is not null.

<Step>
	<Name>fault-resource-not-found</Name>
        <Condition>(responsePrefix.error != null)</Condition>
</Step>

In the above snippet, responsePrefix.error is the value extracted from the response we got from the backend.

And the fault something like

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RaiseFault async="false" continueOnError="false" enabled="true" name="fault-missing-info">
    <DisplayName>fault-missing-info</DisplayName>
    <Properties/>
    <FaultResponse>
        <Set>
            <Headers>
                <Header name="Content-Type">application/json</Header>
            </Headers>
            <Payload contentType="application/json" variablePrefix="#" variableSuffix="%">
            {
                "errors":[
                    {
                        "code": "400",
                        "userMessage": "Missing Info",
                        "systemMessage": "Missing Info"
                    }
                ]
            } 
        </Payload>
            <StatusCode>400</StatusCode>
            <ReasonPhrase>Bad Request</ReasonPhrase>
        </Set>
    </FaultResponse>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>

As you see in the Raise fault policy, you can configure the response message, http code, etc via flow variables.

Hope this helps

View solution in original post

13 REPLIES 13

Not applicable

Check out this similar question: https://community.apigee.com/questions/10879/response-flow-in-case-of-non-success-response-code.html

Will that solution work for your case?

HI @Kumaresan Sithambaram

If there is a difference between the successful response message and an error response message, you can use an extract variable policy and extract the values from the back end response and use a Raise Fault policy to raise an error with an appropriate http code when that variable is not null.

<Step>
	<Name>fault-resource-not-found</Name>
        <Condition>(responsePrefix.error != null)</Condition>
</Step>

In the above snippet, responsePrefix.error is the value extracted from the response we got from the backend.

And the fault something like

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RaiseFault async="false" continueOnError="false" enabled="true" name="fault-missing-info">
    <DisplayName>fault-missing-info</DisplayName>
    <Properties/>
    <FaultResponse>
        <Set>
            <Headers>
                <Header name="Content-Type">application/json</Header>
            </Headers>
            <Payload contentType="application/json" variablePrefix="#" variableSuffix="%">
            {
                "errors":[
                    {
                        "code": "400",
                        "userMessage": "Missing Info",
                        "systemMessage": "Missing Info"
                    }
                ]
            } 
        </Payload>
            <StatusCode>400</StatusCode>
            <ReasonPhrase>Bad Request</ReasonPhrase>
        </Set>
    </FaultResponse>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>

As you see in the Raise fault policy, you can configure the response message, http code, etc via flow variables.

Hope this helps

@Sai Saran Vaidyanathan

Thanks !! Does responsePrefix is predefined which reads from XML or JSON ? My output default variable is response.

Hi @Kumaresan Sithambaram

No, responsePrefix is the Variable prefix I have on my ExtractVariable policy. You need to pass your response into the Extract Variable as Source and then use the extracted variable in the Condition.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="extract-baas-response">
    <DisplayName>extract-response</DisplayName>
    <Properties/>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <JSONPayload>
        <Variable name="entities" type="nodeset">
            <JSONPath>$.entities</JSONPath>
        </Variable>
        <Variable name="error" type="string">
            <JSONPath>$.error</JSONPath>
        </Variable>
        <Variable name="error_description" type="string">
            <JSONPath>$.error_description</JSONPath>
        </Variable>
    </JSONPayload>
    <Source clearPayload="false">response</Source>
    <VariablePrefix>responsePrefix</VariablePrefix>
</ExtractVariables>

After the above Extract policy is executed, responsePrefix.error will have a value when an error is sent from the target. Using that you can have a Condition in your flow

<Step>
	<Name>resource-not-found</Name>
        <Condition>(responsePrefix.error != null)</Condition>
</Step>

and Raise a Fault. In my case I am extracting the error_description also and using that when building the Fault policy custom payload. Something like this

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RaiseFault async="false" continueOnError="false" enabled="true" name="resource-not-found">
    <DisplayName>resource-not-found</DisplayName>
    <Properties/>
    <FaultResponse>
        <Set>
            <Headers>
                <Header name="Content-Type">application/json</Header>
            </Headers>
            <Payload contentType="application/json" variablePrefix="#" variableSuffix="%">
            {
                "errors":[
                    {
                        "code": "Not Found",
                        "userMessage": "#responsePrefix.error%",
                        "systemMessage": "#responsePrefix.error_description%"
                    }
                ]
            } 
            </Payload>
            <StatusCode>404</StatusCode>
            <ReasonPhrase>Not Found</ReasonPhrase>
        </Set>
    </FaultResponse>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>

Hope this clarifies. Please accept if it does

@Sai Saran Vaidyanathan

That works !! But, i want set only Status Code. Because, My Service Errors are handled at transformation and displayed in UI. I would like to set only Status Code other than 200Ok. If i use Raise Fault before or after Raise Fault, my formatted error by xsl transformation is overwritten. Is that best to set only Bad Request with Status Code like 404 ?

Will this help ?

I followed this approach.

Step 1) Conditionally Checking and calling Assign Message Policy after my final transformed response.

 <Step>
                <Condition>responsePrefix.status == "Failed"</Condition>
                <Name>AMBackend-Service-Fault</Name>
            </Step>

Step 2) if condition satisfied then putting the response.content in Assign Message Policy like this.

But, not sure whether good recommended solution or not.

 <Set>
        <Headers>
            <Header name="Content-Type">application/json</Header>
        </Headers>
        <Payload contentType="application/json" variablePrefix="@" variableSuffix="#">"@response.content#"</Payload>
        <StatusCode>404</StatusCode>
        <ReasonPhrase>Bad Request</ReasonPhrase>
    </Set>				

But, the above Approach the the response is not formatted as per JSON standard.

@Sai Saran Vaidyanathan Is that anyway to set the http status code & reason phrase using Java script ?

@Sai Saran Vaidyanathan That works !! Thanks a Lot !

HI

I would recommend Raise Fault policy for any error responses instead of Assign Message. Change your AMBackend-Service-Fault policy to a Raise Fault policy - more details here

 <FaultResponse>
   <Set>
     <StatusCode>404</StatusCode>
     <ReasonPhrase>Bad Request</ReasonPhrase>
   </Set>
 </FaultResponse>

No need to set the payload

You should see the response payload with the above set code and reason