Parameters as Directives
Any part of a request can be used to route and accept or reject the request. Request parameters, encoded in a query string or a POST request body, are an open field for richer requests -- and user error. We can handle these with directives as well.
In HTTP, a parameter key can be specified multiple times with different values. Unfiltered's base model for parameters is therefore a string key to a sequence of string values in the order they were supplied. This is easy to obtain in a directive.
You can try this service with multiple, one, or no parameters.
curl -v http://127.0.0.1:8080/ -d in=one -d in=two
Even with no parameters, the directive succeeds with an empty sequence. Since it's not establishing control flow, we could have accessed it just as easily through the @ref:Params map. But typically, we do have requirements on our input.
I'm thinking of a Number
Things get more interesting when require parameters to be in a
particular format. From here on out, we'll be working with
interpreters in the @extref
package. Interpreters define abstract operations on data; we can
produce directives for a particular request parameter with
By testing this service you'll find that all requests to the root path
are accepted, and that the
in value is bound to an
in request parameter is not present or not a valid int, the value
None. This is a directive, but it's still one that always
What about repeated parameters? The object
data.as.Int is an
Int, but in HTTP we model parameter
values as a sequence of strings. This gap is bridged by another
data.as.String, which chooses the first in the
sequence. It's applied implicitly when needed.
We can transform an interpreter that ignores failed interpretation
into one that produces a failure response by passing an error handler
The error handling function receives both the parameter name and given value as parameters. This way, a directive used for more than one parameter can have a specific error message for each.