Change and Set the HTTP status code Response

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?

1 Like

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

1 Like

@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.

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

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

@Kumaresan Sithambaram

Check this link

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

check in this link

https://community.apigee.com/questions/52492/customizing-http-status-code.html?childToView=52555#answer-52555