I think you need a truth table. Something to help express exactly what should be allowed and not allowed.
First let us stipulate that only GET /person requests will be allowed. Any non-GET or any GET on something other that /person, will be rejected. So the eventual condition must consider that, but in the truth table we want to look only at query param presence.
| name |
number |
houseNo |
place |
Allow? |
| not present |
either |
either |
either |
NO |
| present |
not present |
either |
either |
NO |
| present |
present |
not present |
either |
NO |
| present |
present |
present |
not present |
YES |
| present |
present |
present |
present |
?? |
| ? |
? |
? |
? |
? |
If I understand correctly you want to allow requests only if they include qparams {name, number, houseNo} . And I am not sure about rejecting or allowing requests with place.
After you get the truth table, translating that into a Condition should be relatively easy. I think the building blocks are
- verb GET
- pathsuffix /person
- qparams name, number, houseNo present
- don’t care about any other qparams
in which case your condition is
<Condition> request.verb = "GET" AND
proxy.pathsuffix ~~ "/person/?" AND
request.queryparam.name != null AND
request.queryparam.number != null AND
request.queryparam.houseNo != null</Condition>
Conditions like this are usually employed in “Conditional Flows” in Apigee. For example, like this:
<ProxyEndpoint name='endpoint1'>
...
<Flows>
<Flow name='flow1'>
<Condition> request.verb = "GET" AND
proxy.pathsuffix ~~ "/person/?" AND
request.queryparam.name != null AND
request.queryparam.number != null AND
request.queryparam.houseNo != null</Condition>
<Request>
...policy steps for request...
</Request>
<Response>
...policy steps for response...
</Response>
</Flow>
...
Keep in mind you can add validation within the flow, to provide better feedback to the calling client app. Often people use a “verb + path” check in the condition for the flow, and then subsequent validation of the headers or queryparams within the flow. For example, like this:
<ProxyEndpoint name='endpoint1'>
...
<Flows>
<Flow name='flow1'>
<Condition> request.verb = "GET" AND proxy.pathsuffix ~~ "/person/?"</Condition>
<Request>
<Step>
<!-- reject calls that do not have the required qparams -->
<Condition>request.queryparam.name = null OR
request.queryparam.number = null OR
request.queryparam.houseNo = null</Condition>
<Name>RF-Invalid-Request-Missing-Qparam</Name>
</Step>
...more policy steps for request...
</Request>
<Response>
...policy steps for response...
</Response>
</Flow>
...
And in this case RF-Invalid-Request is a RaiseFault policy that sends back a message indicating that there is a missing qparam.
This is the kind of structure I recommend. Then augment that with a “catch all flow” that responds when the request is not GET /person. Like so:
<ProxyEndpoint name='endpoint1'>
...
<Flows>
<Flow name='flow1'>
<Condition> request.verb = "GET" AND proxy.pathsuffix ~~ "/person/?"</Condition>
<Request>
<Step>
<!-- reject calls that do not have the required qparams -->
<Condition>request.queryparam.name = null OR
request.queryparam.number = null OR
request.queryparam.houseNo = null</Condition>
<Name>RF-Invalid-Request-Missing-Qparam</Name>
</Step>
...more policy steps for request...
</Request>
<Response>
...policy steps for response...
</Response>
</Flow>
<Flow name='unsupported-request'>
<!-- no condition here. it handles all requests not matched above -->
<Request>
<Step>
<Name>RF-Bad-Request</Name> <!-- will send back 400 or 404 -->
</Step>
</Request>
</Flow>
</Flows>
...