You have a couple options for implementing that validation in Apigee .
- Condition elements in the flow.
- custom policy, for example written in JavaScript
In more detail.
In the flow language of Apigee, you can use Condition elements that tell Apigee under what condition to execute various steps. One pattern you may use to test for all 22 cases is: a compound Condition that tests for a particular value of the query param “code” and then the false Condition for the ID.
in pseudo language
If the Code is AT and the id is not 9 alphanumeric characters, then return fault 1.
if the Code is BE and the id is not 10 decimal digits, then return fault 2.
You can rely on regular expression matching in Conditions to check for strings. In actual flow language, it would look like this:
<Step>
<Name>RaiseFault-InvalidParameter</Name>
<Condition>request.queryparam.code = "AT" and NOT(request.queryparam.id ~~ "[0-9]{9}")</Condition>
</Step>
<Step>
<Name>RaiseFault-InvalidParameter</Name>
<Condition>request.queryparam.code = "BE" and NOT(request.queryparam.id ~~ "[A-Z0-9]{10}")</Condition>
</Step>
...
Of course, you could also combine ALL of those into one large compound Condition.
<Step>
<Name>RaiseFault-InvalidParameter</Name>
<Condition>
(request.queryparam.code = "AT" and
NOT(request.queryparam.id ~~ "[0-9]{9}")) OR
(request.queryparam.code = "BE" and
NOT(request.queryparam.id ~~ "[A-Z0-9]{10}")) OR
...
</Condition>
</Step>
You also need to consider edge cases, in which code is not present, or code is “none of the above.”
The RaiseFault policy just returns what you said you wanted:
<RaiseFault name='RaiseFault-InvalidParameter'>
<FaultResponse>
<Set>
<Payload contentType='application/json'>{"errorCode": 1001, "errorCode": "Invalid parameter"}
</Payload>
<StatusCode>400</StatusCode>
<ReasonPhrase>Bad Request</ReasonPhrase>
</Set>
</FaultResponse>
</RaiseFault>
That might be readable to you. If you don’t like the flow conditions, then you can use JavaScript to implement the checks of regular expressions and Code. In the flow, this might look like this.
<Step>
<Name>JS-ValidateQuery</Name>
</Step>
And in JavaScript:
var patternMappings = {
AT : "[0-9]{9}",
BE : "[A-Z0-9]{10}",
..
};
var code = context.getVariable('request.queryparam.code');
if (code) {
if (patternMappings[code]) {
var re = new RegExp("^" + patternMappings[code] + "$");
var id = context.getVariable('request.queryparam.id');
if (!id.match(re)) {
throw new Error("Invalid id parameter");
}
}
else {
throw new Error("unknown code");
}
}
else {
throw new Error("missing code");
}
If you throw from JavaScript, it results in a Fault condition in the Apigee flow. You can use a FaultRule to handle that, and within that, AssignMessage to assign the payload to be
{"errorCode": 1001, "errorCode": "Invalid parameter"}
Either Conditions in flows, or JavaScript will work. Which of these you prefer depends on your sense of which is more readable.