API proxy with POST and non default ROUTE giving 405 Response

I created a API proxy with default route and another route which goes to a different target endpoint ..

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
    <Description/>
    <FaultRules/>
    <PreFlow name="PreFlow">
        <Request/>
        <Response/>
    </PreFlow>
    <PostFlow name="PostFlow">
        <Request/>
        <Response/>
    </PostFlow>
    <Flows/>
    <HTTPProxyConnection>
        <BasePath>/gastrowatch</BasePath>
        <Properties/>
        <VirtualHost>default</VirtualHost>
        <VirtualHost>api-d</VirtualHost>
    </HTTPProxyConnection>
    <RouteRule name="publish">
        <Condition>(proxy.pathsuffix MatchesPath "/publish") and (request.verb == "POST")</Condition>
        <TargetEndpoint>publish</TargetEndpoint>
    </RouteRule>
    <RouteRule name="default">
        <TargetEndpoint>default</TargetEndpoint>
    </RouteRule>
</ProxyEndpoint>

When I do the default route it works but when I do my /publish with POST in postman I get the following error

{
    "fault": {
        "faultstring": "Received 405 Response without Allow Header",
        "detail": {
            "errorcode": "protocol.http.Response405WithoutAllowHeader"
        }
    }
}

The /publish target endpoint looks as follows

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TargetEndpoint name="publish">
    <Description/>
    <FaultRules/>
    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Name>PIKM-Hub-Get-User-Crendentials</Name>
            </Step>
            <Step>
                <Name>add-cors</Name>
            </Step>
            <Step>
                <Name>modifyPublishParams</Name>
            </Step>
            <Step>
                <Name>PIKM-HUB-DEV-AUTH</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>
    <PostFlow name="PostFlow">
        <Request/>
        <Response/>
    </PostFlow>
    <Flows/>
    <HTTPTargetConnection>
        <Properties/>
        <URL>http://xxxx:8011/LATEST/resources/wos_article_add_collections</URL>
    </HTTPTargetConnection>
</TargetEndpoint>

Not sure what I am doing wrong, can someone help as to what I am doing wrong ?

1 7 1,604
7 REPLIES 7

The fault is generated by Apigee Edge. But is it possible your backend is returning a 405? You can verify this by turning on Trace in Apigee Edge.

It is the Apigee server only.. as I don;t see any thing on the target endpoint server. The thing is when I add the following route rule it works.. But not sure why.. can someone let me know why this is

 <RouteRule name="NoRoute">
     <Condition>(request.verb == "POST")</Condition>
 </RouteRule>

I don;t see any thing on the target endpoint server.

I'm not sure what that means, but the message that Apigee Edge is returning, specifically:

{
    "fault": {
        "faultstring": "Received 405 Response without Allow Header",
        "detail": {
            "errorcode": "protocol.http.Response405WithoutAllowHeader"
        }
    }
}

...is telling you that APIGEE EDGE received a 405 response without an Allow Header. This implies that Apigee Edge did connect to the backend system and received an actual response. That response did not also include an Allow header; this violates the spec.

The server MUST generate an Allow header field in a 405 response containing a list of the target resource's currently supported methods.

So your backend is sort of broken. And Apigee Edge is strict about the 405 response, so Apigee Edge is going into Fault processing because the response is wrong. But, You may be able to avoid this error by sending the appropriate thing to the backend.

The 405 from the backend implies that something in the message being received by the backend is not right, not valid. So you need to consider what Apigee Edge is sending the backend and make sure it complies with what the backend expects. If you get it right, then the backend won't respond with 405's , and then Apigee Edge won't choke on a broken 405, if you get my meaning.

When you add the routerule like this:

 <RouteRule name="NoRoute">
     <Condition>(request.verb == "POST")</Condition>
 </RouteRule>

...you are telling the ProxyEndpoint to NOT send anything to the backend when the inbound request is a POST. The reason this "works" is because the proxy doesn't send anythign to the backend, so the backend has no chance to return a response, whether a 405 or otherwise.

So it's not really "working", I guess. It's just that your routerule effectively stubs out the part of the Apigee Edge system that would connect with the backend.

No Actually when I have "NoRoute" then my /publish with POST works fine.. I also noticed that instead of create a route for /publish.. I created another API proxy and that works as well.

The "NoRoute" RouteRule you showed... causes Apigee Edge to NOT connect to the backend. If your observation is that "it works", and a call is actually being sent by Apigee to the backend system, then somehow your analysis of the situation is incomplete, or your understanding of the configuration of the proxy is not correct.

where can I look what is being sent by apigee.. does it log anywhere.. I have access to the apigee server. Trace session doesn't work for me .. it complains it cannot connect.

You can look in the Trace UI. If you cannot use the Trace UI, then you should get that fixed. You have myriad problems.