Irrespective of the involvement in Apigee Edge in collapsing a double ampersand to a single ampersand, relying on the double-ampersand trick to represent a “missing” queryparam seems like a bad idea.
We need the querystring to contain all the query parameters because since they are not key/value pairs we need to parse the querystring positionally and with the && being removed is throwing off the positions.
I may be coming at this with a naive viewpoint, but I don’t understand “we need to parse the querystring positionally”. I don’t think that is so. For example, you could parse them in JavaScript callout, like this:
// When retrieving queryparam names, convert the set to a string:
var names = context.getVariable('request.queryparams.names') + '';
// result is a string, like so: "[name1,name2]"
// or "[]" in the case of no query params passed.
// To then get an array of names, use substring and split:
names = names.substring(1,names.length-1).split(',');
// names = [ 'name1', 'name2' ]
var values = [];
var trimmed_names = [];
var hash = {};
names.forEach(function(n){
n = n.trim();
if (n) {
var varname = 'request.queryparam.' + n;
var v = context.getVariable(varname);
values.push(v?v:'(blank)');
trimmed_names.push(n);
hash[n] = v;
}
});
context.setVariable('qparam_names', JSON.stringify(trimmed_names));
context.setVariable('qparam_values', JSON.stringify(values));
context.setVariable('qparam_hash', JSON.stringify(hash));
If you include a JS policy like the above, and then add an AssignMessage policy like so:
<AssignMessage name='AM-Response'>
<Set>
<Payload contentType='application/json'>{
"qparams" : {
"names" : {qparam_names:[]},
"values" : {qparam_values:[]},
"hash" : {qparam_hash:null}
}
}
</Payload>
<StatusCode>200</StatusCode>
<ReasonPhrase>OK</ReasonPhrase>
</Set>
</AssignMessage>
Then, with this request:
curl -i [http://myorg-myenv.apigee.net/queryparams1/t1?1&3&other=7](http://myorg-myenv.apigee.net/queryparams1/t1?1&3&other=7)
you will see this response:
{
"qparams" : {
"names" : ["1","3","other"],
"values" : ["(blank)","(blank)","7"],
"hash" : {"1":null,"3":null,"other":"7"}
}
}
I suppose you would want to compare the received query params against the possible expected query params, and then you would find which ones were “missing”.