On 5/22/2014 11:01, Josh Chamas wrote:

You know I have not much followed the routing paradigms.  To me it seems
that this would be an area I would have solved with a mod_rewrite or a
mod_perl handler, changing up the URL destination on the back end.

Routing is more than just an abstraction between the implementation level and the presentation to the browser. It forces you to consider your logical URL structure.

My Apache::ASP code just growed, like Topsy. One page at a time, with no consideration of the interfaces exposed by the other pages. There was consistency of design only to the extent that there was code copying, and then in decreasing fashion with respect to time, as the cloned pages diverged.

As soon as I started developing a system of routes in the Dancer port, I realized that I had an API. It was sitting there the whole time, never identified in the Apache::ASP form, but there it was in the Dancer code, clear as day. Once I'd formally extracted it, I spent a day redesigning it the way it should always have been. The correct design popped right out, obvious as a green sky.

This happens because you have to describe your URL structure to Dancer, one URL per line. Many fit in a single screen of text, so patterns jump out at you.

Example in Dancer pseudocode:

    get '/' => ...
    get '/login' => ...
    get '/logout' => ...

    prefix '/app' => sub {
        get 'page1' => ....
        get 'page2' => ....
    };

    prefix '/api' => sub {
        del  'foo/:id' => ...
        get  'foo/:id' => ...
        post 'foo' => ...
        put  'foo' => ...

        get  'bar/:id' => ...
        ...same as foo...
    };

The story this route structure tells is clear:

1. First you go to the top level page, which perhaps has a Log In link or button to send you to the /login page.

2. The /login page creates a session and bounces you to /app when you log in successfully.

3. There's a button or link somewhere that sends you to /logout, which destroys your session and sends you back to / or /login.

4. The app does CRUD-y things to "foo" and "bar" objects through /api/{foo,bar}, creating via PUT, reading via GET, updating via POST, and deleting via DELETE. GET and DELETE require a record ID to tell the handler what to operate on, while PUT and POST must be fairly complex in what they will accept, so that the parameters cannot be marked as required in the route structure.

It's kind of like that Fred Brooks quote, "Show me your flowcharts and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won’t usually need your flowcharts; they’ll be obvious."

I wonder if Apache::ASP were to be made to work
with something like Plack, if it would pick up some routing potential on
the way (or maybe just a Plack way of doing things?)

I don't think so. I believe a minimum-effort Apache::ASP Plack port would have only one feature relative to Apache::ASP v2, that being web stack independence. From your perspective, the big difference is that you have to replace all the mod_perl Apache2::Foo stuff with Plack/PSGI equivalents.

To get a handle on what routing does for Dancer, say:

    $ sudo cpanm Dancer
    $ dancer -a foo

This generates a complete, self-contained sample app, suitable for hacking on directly. That is to say, the file and directory structure it generates is suitable for production use.

The routing structure is in foo/lib/foo.pm. You also use this file to define hooks, which are roughly equivalent to global.asa event handlers in Apache::ASP. Script_OnStart is the same as Dancer's "before" hook, for example. There is no direct equivalent of Session_OnStart, but you can build that into the "before" hook, too. The Dancer equivalent to the Application_* event handlers is foo/bin/app.pl.

If Apache::ASP were to get a routing system, I don't know that you'd necessarily want to put it in global.asa. It works well for Dancer, but perhaps another design would make more sense for Apache::ASP, since global.asa has historical meaning.

Notice, by the way, that foo/lib gets added to @INC by foo/bin/app.pl. This solves another problem I had with Apache::ASP, which doesn't like you to define functions and classes in your *.asp files. You end up creating *.pm files to hold all reused and complicated code. Where then do you put those *.pm files so that mod_perl can find them?

In my Apache::ASP app, I ended up installing them into the system's site_perl directory, and then I could never remember the path to those files when I had to hand-hack one of these files on a production server to test a problem fix in the field. With Dancer, the *.pm files are right there next to the rest of the app.

The most problem with Apache::ASP for by now is that it is tied to
mod_perl
with it's module reloading ,memory hogging problems.


Yes, always been a problem, but memory is so cheap! :)

I know you're joking, but RAM on VPSes isn't cheap. 4 GB more RAM in my colocated box is virtually free. 4 GB of RAM added to my cheap bare-bones VPS plan adds another $35/mo, or $420/yr, or $2,100 over the expected lifetime of the server.

There's another advantage of Dancer. By going with a single long-lived app process instead of forking off Apache children, and by making that app independent of tubby ol' Apache, we can squeeze our app into much smaller VPSes and VMs.

In extreme situations, you don't even need a traditional web server. That "foo" app I had you create above? It contains a perfectly usable basic web server, listening on port 3000. Run it as root so it can bind to port 80 instead or port-forward 80 to it, and you've got an entirely self-contained app.

---------------------------------------------------------------------
To unsubscribe, e-mail: asp-unsubscr...@perl.apache.org
For additional commands, e-mail: asp-h...@perl.apache.org

Reply via email to