The following (not very carefully considered) thoughts spring to mind...
Would you consider making it more generic, and not tied specifically to CGI? It might be nice to have in a mod_perl handler too, where we might assume $r instead of $q, and any other variations as well.
If you do this, you would no doubt create a base despatch and validation class, and then specialise this to provide natural args in each environment - e.g. a CGI implementation would provide natural CGI args, and a mod_perl method would provide the request handle $r etc.
The subs will probably need standardised, but more complex arg handling - how about something like:
On validation of params, you might consider an additional section for validation subs for the named args/edit?items=[(\w+)];location=(\w+);flags={(\d+)};... { if ( $arg->{location} eq 'US' ) { for my $item ( @{$arg->{items}} ) { if ( $arg->{flags}{54} ) { $r->print "item: $item qualifies for discount 54 processing< +br>\n"; } } } # other optional args that we may / may not have if ( defined $arg->{style} ) { $r->print("you have style! $arg->{style}<br>\n" } }; # args are placed in hashref $arg # [] indicates that the named arg should be an array. # {} indicates that the named arg should be a hash. # for a URL of flags=54&flags=23&flags=red # might yeild # $arg->{flags} = { # 54 => 54, # 23 => 23, # red => 'red', # }; # so that programmers can use keys values as they are comfy? # optional args (ie the ...) are available in $arg
:DESPATCH /edit?node=(\w+);... { print "You're trying to edit '$node'"; }; :PARAM node { my ( $node ) = @_; my $db = My::Database->new(...); return $node if $db->selectValue( sql => "select count(*) from nod +es where node=?", param => [$node] ); print "invalid node: $node"; return undef; }
The despatch fall-through case /(.*) should probably be handled by the despatch class, by default - it will have to do something if nothing matches!
You will also have to resolve conflicts where a URL matches more than one sub
/edit?name=(\w+);city=(\w+);... { print "Edit '$name' in '$city'"; }; /edit?name=(\w+);job=(.*);... { print "Edit '$name' who does '$job'"; };
Various approaches spring to mind, generally the most specific wins, but if the despatch matches are equally specific?
Regards,
Jeff
In reply to Re: Mapping URLs to code - in search of perlish dispatch schemes
by jaa
in thread Mapping URLs to code - in search of perlish dispatch schemes
by Corion
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |