When I changed the method from "GET" to "POST," I got "400 Bad Request," which is not good at all. I have a flow that will trigger if the user changes the method. I need to bypass the OAS validation so that the "method not allowed" error message appears in my response. I put the OAS validation policy in the Proxy Endpoint/PreFlow.
Solved! Go to Solution.
When I try an OASValidation step, I get a verbose error message that indicates why the OASValidation has rejected my request. The message identifies that the path is wrong, or the verb is wrong, or whatever. Is that not what you see?
$ curl -i -X POST $endpoint/oas-test1/t1
HTTP/2 400
content-type: application/json
apiproxy: oas-test1 r1
x-request-id: c8ffd787-13f8-4629-a3c8-3945779db12f
content-length: 227
date: Wed, 21 Dec 2022 17:46:58 GMT
via: 1.1 google
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
{"fault":{"faultstring":"OASValidation OAS-1 with resource \"oas:\/\/test-spec1.yaml\": failed with reason: \"[ERROR - No API path found that matches request '\/t1'.: []]\"","detail":{"errorcode":"steps.oasvalidation.Failed"}}}
$ curl -i -X POST $endpoint/oas-test1/persons/13
HTTP/2 400
content-type: application/json
apiproxy: oas-test1 r1
x-request-id: e59332d6-5fc4-4a7b-86f7-73094771ca39
content-length: 232
date: Wed, 21 Dec 2022 17:47:09 GMT
via: 1.1 google
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
{"fault":{"faultstring":"OASValidation OAS-1 with resource \"oas:\/\/test-spec1.yaml\": failed with reason: \"[ERROR - POST operation not allowed on path '\/persons\/13'.: []]\"","detail":{"errorcode":"steps.oasvalidation.Failed"}}}
If you don't like the "standard" error messages that get generated from the policy, You can use FaultRules within the proxy to override them and substitute your own. To do that, introduce this in your proxy endpoint:
<ProxyEndpoint name="endpoint1">
<Description>...</Description>
<HTTPProxyConnection>
....
</HTTPProxyConnection>
<FaultRules>
<FaultRule name='rule1'>
<Step>
<Name>JS-Override-Message</Name>
</Step>
<Condition>fault.name = "Failed" AND fault.subcategory = "OASValidationFailure"</Condition>
</FaultRule>
</FaultRules>
...
And the JavaScript step can look like this:
<Javascript name='JS-Override-Message' >
<Source><![CDATA[
var r = context.getVariable('fault.reason');
var m = r.match(new RegExp('\\[ERROR - (.+?)\\..+'));
if (m) {
r = {error: m[1]};
context.setVariable('message.content', JSON.stringify(r, null, 2) + '\n');
}
]]>
</Source>
</Javascript>
Basically, you are overriding the message content, without changing the 400 status code or "Bad Request" status string. The "400" and "Bad Request" seem appropriate to me.
When I do this I get this kind of result:
curl -i -X POST $endpoint/oas-test1/persons/13
HTTP/2 400
content-type: application/json
apiproxy: oas-test1 r7
x-request-id: 91a3dddd-0214-4f13-a038-37149537000a
content-length: 66
date: Wed, 21 Dec 2022 18:17:20 GMT
via: 1.1 google
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
{
"error": "POST operation not allowed on path '/persons/13'"
}
For the curious, when the OASValidation step rejects an inbound request, it sets a fault. You can retrieve these context variables that reference it:
property name | expected value |
---|---|
fault.name | Failed |
fault.reason | OASValidation OAS-1 with resource "OAS-SPEC-HERE": failed with reason: "[ERROR - REASON-STRING-HERE: []]" |
fault.category | Step |
fault.subcategory | OASValidationFailure |