Sounds great!

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:

/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&amp;flags=23&amp;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
On validation of params, you might consider an additional section for validation subs for the named args
: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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.