Plack::Middleware::PeriAHS::ParseRequest - Parse Riap request from HTTP request
version 0.14
# in your app.psgi use Plack::Builder; builder { enable "PeriAHS::ParseRequest", match_uri => m!^/api(?<uri>/[^?]*)!; };
This middleware's task is to parse Riap request from HTTP request (PSGI environment) and should normally be the first middleware put in the stack.
The result of parsing will be put in $env-{"riap.request"}> hashref.
$env-
Aside from that, this middleware also sets these for convenience of later middlewares:
$env->{'periahs.default_fmt'} => STR
Default output format, will be used for response if fmt is not specified in Rinci request. Determined using some simple heuristics, i.e. graphical browser like Firefox or Chrome will get 'HTML', command-line browser like Wget or Curl will get 'Text', others will get 'json'.
fmt
$env->{'periahs.jsonp_callback'} => STR
From form variable callback.
callback
$env->{'periahs.riap_client'} => OBJ
Store the Riap client (instance of Perinci::Access).
From HTTP header and request body. First parsing is done as per Riap::HTTP specification's requirement. All X-Riap-* request headers are parsed for Riap request key. When an unknown header is found, HTTP 400 error is returned. Then, request body is read for args. application/json document type is accepted, and also text/yaml (if accept_yaml configuration is enabled).
X-Riap-*
args
application/json
text/yaml
accept_yaml
Additionally, the following are also done:
From URI. Request URI is checked against match_uri configuration. If URI doesn't match this regex, a 404 error response is returned. It is a convenient way to check for valid URLs as well as set Riap request keys, like:
qr!^/api/(?<fmt>json|yaml)/!;
The default match_uri is qr/(?<uri>[^?]*)/.
match_uri
From form variables. If parse_form is enabled, args request key will be set (or added) from GET/POST request variables, for example: http://host/api/foo/bar?a=1&b:j=[2] will set arguments a and b (":j" suffix means value is JSON-encoded; ":y" and ":p" are also accepted if the accept_yaml configurations are enabled). In addition, request variables -riap-* are also accepted for setting other Riap request keys. Unknown Riap request key or encoding suffix will result in 400 error.
parse_form
a
b
-riap-*
If request format is JSON and form variable callback is defined, then it is assumed to specify callback for JSONP instead part of args. "callback(json)" will be returned instead of just "json".
From URI (2, path info). If parse_path_info configuration is enabled, and uri Riap request key has been set (so metadata can be retrieved), args will be set (or added) from URI path info. See "parse_path_info" in the configuration documentation.
From URI (2, path info)
parse_path_info
uri
http://host/api/v1/Module::Sub/func/a1/a2/a3
will result in ['a1', 'a2', 'a3'] being fed into Perinci::Sub::GetArgs::Array. An unsuccessful parsing will result in HTTP 400 error.
match_uri => REGEX or [REGEX, CODE] (default qr/.?/)
This provides an easy way to extract Riap request keys (typically uri) from HTTP request's URI. Put named captures inside the regex and it will set the corresponding Riap request keys, e.g.:
qr!^/api(?<uri>/[^?]*)!
If you need to do some processing, you can also specify a 2-element array containing regex and code. When supplied this, the middleware will NOT automatically set Riap request keys with the named captures; instead, your code should do it. Code will be supplied ($env, \%match) and should set $env->{'riap.request'} as needed. An example:
match_uri => [ qr!^/api (?: /(?<module>[\w.]+)? (?: /(?<func>[\w+]+) )? )?!x, sub { my ($env, $match) = @_; if (defined $match->{module}) { $match->{module} =~ s!\.!/!g; $env->{'riap.request'}{uri} = "/$match->{module}/" . ($match->{func} // ""); } }];
Given URI /api/Foo.Bar/baz, uri Riap request key will be set to /Foo/Bar/baz.
/api/Foo.Bar/baz
/Foo/Bar/baz
accept_yaml => BOOL (default 0)
Whether to accept YAML-encoded data in HTTP request body and form for args Riap request key. If you only want to deal with JSON, keep this off.
parse_form => BOOL (default 1)
Whether to parse args keys and Riap request keys from form (GET/POST) variable of the name -x-riap-* (notice the prefix dash). If an argument is already defined (e.g. from request body) or request key is already defined (e.g. from X-Riap-* HTTP request header), it will be skipped.
-x-riap-*
parse_path_info => BOOL (default 0)
Whether to parse arguments from $env->{PATH_INFO}. Note that this will require a Riap meta request to the backend, to get the specification for function arguments. You'll also most of the time need to prepare the PATH_INFO first. Example:
meta
parse_path_info => 1, match_uri => [ qr!^/ga/(?<mod>[^?/]+)(?: /?(?: (?<func>[^?/]+)?: (<pi>/?[^?]*) ) )!x, sub { my ($env, $m) = @_; $m->{mod} =~ s!::!/!g; $m->{func} //= ""; $env->{'riap.request'}{uri} = "/$m->{mod}/$m->{func}"; $env->{PATH_INFO} = $m->{pi}; }, ]
riap_client => OBJ
By default, a Perinci::Access object will be instantiated (and later put into $env-{'periahs.riap_client'}> for the next middlewares) to perform Riap requests. You can supply a custom object here.
Perinci::Access::HTTP::Server
Steven Haryanto <stevenharyanto@gmail.com>
This software is copyright (c) 2012 by Steven Haryanto.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
To install Perinci::Access::HTTP::Server, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Perinci::Access::HTTP::Server
CPAN shell
perl -MCPAN -e shell install Perinci::Access::HTTP::Server
For more information on module installation, please visit the detailed CPAN module installation guide.