ANNOUNCE: MasonX::WebApp 0.01

2004-05-11 Thread Dave Rolsky
This is the first release of this code, and it's probably buggy, but I
think it's pretty neat.

>From the docs ...

=head1 SYNOPSIS

  # Create a subclass of MasonX::WebApp
  package My::WebApp;

  use base 'MasonX::WebApp';

  sub _init
  {
  # do neat stuff
  }

  # In your Apache config file

  
SetHandler   perl-script
PerlHandler  My::WebApp
  

=head1 DESCRIPTION

C works with Mason to let you do processing I
Mason is ever invoked.  There are a number of things that one might
want to do:

=over 4

=item * Argument munging

You might want to make sure all incoming arguments are UTF-8 encoded.
Or you might want to create some objects which Mason will see as
incoming arguments.  For example, a "user_id" parameter could be
turned into a user object.

=item * Handle requests without Mason

If you're not generating output for the browser other than a redirect,
then there's no reason to use Mason.  You can use a C
subclass to handle all form submissions, for example.

This has the added benefit of making it easier to preload this code
once during server startup.

=item * Authorization checks

Why do authorization checks in Mason if a failed check just leads to a
redirect or NOT FOUND return code?

=back



-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/

-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html



Re: ANNOUNCE: MasonX::WebApp 0.01

2004-05-12 Thread John Siracusa
>From the docs:

> You must call clean_request_args() on the ApacheHandler object at the end of
> the request, unless you are making a new ApacheHandler object for every
> request. Otherwise bad things will happen.
> 
> This is lame, so if someone thinks of a better way to do this, I'd be happy to
> hear about it.

In my massively more complicated (in both the good and bad senses of the
word), but spiritually similar Mason-using WebApp framework, I do something
like this:

---


  PerlSetVar WebAppClass "WebApp::Foo::Bar"
  SetHandler perl-script
  PerlHandler Apache::WebApp


---

# Apache/WebApp.pm

our(%Apps, $Interp); # caches

sub handler($$)
{
  my($self, $r) = @_;

  $self = $self->new($r)  unless(ref $self);
  $self->sanity_check() or return $self->status;
  my $app = $self->app;
  $self->parse_query($r, $app)  or return $self->status;

  return $self->handle_request($r, $app);
}

...

# "app" is a "get, set, init" attribute (c.f. Class::MethodMaker)
sub init_app 
{
  my($self) = shift;

  my $r = $self->apache_request;

  my $class = $r->dir_config('WebAppClass')
or die "No WebAppClass defined for this location: ",  $r->uri;

  if($r->dir_config('WebAppNoAppCache'))
  {
return $class->new();
  }
  else
  {
return $Apps{$class} ||= $class->new();
  }
}

sub init_mason_interp { $Interp ||= ... } # more "get, set, init"

sub handle_request
{
  my($self, $r, $app) = @_;

  $app->refresh();

  $app->params($self->params);
  $app->mason_interp($self->mason_interp);

  $app->run();

  my $status = $app->status;

  $app->clear();

  return $status;
}

---

# WebApp/Foo/Bar.pm

package WebApp::Foo::Bar;

use strict;

use WebApp;
our @ISA = qw(WebApp);

sub root_uri { '/foo/bar' } # duplicated, but oh well
...

---

Basically, I try to separate the thing that dispatches incoming requests
(Apache::WebApp) and the things that are dispatched to (the actual apps,
e.g. WebApp::Foo::Bar)

Every  directive has the same PerlHandler (Apache::WebApp) but
different WebAppClass  settings.

Of course, I'm free to subclass any of these classes to make some sort of
specialized behavior, but so far, the basic "dumb caching" dispatcher
(Apache::WebApp) has done everything I need.

But getting back to the point of this post, Apache::WebApp is where I do all
the per-request setup and cleanup, not in the apps themselves.  That way,
writing a WebApp doesn't involve worrying about any of the boring setup and
cleanup stuff that every app needs to do in order to work correctly (e.g.
Not have any stale data left over)

Session cleanup/save-back can be done either in the Apache::WebApp
dispatcher or at the end of the app objects' run() method.  In practice, I
do it in the dispatcher and also in some apps, using a save_if_modified()
method which is inexpensive enough that I don't care about duplicated calls.

You'll also notice that I do a "$app->refresh" before and a "$app->clear"
after processing a request in the dispatcher.  This is because some apps may
choose to "empty" themselves when not in use, even if they app object is
still cached in %apps.  So "clear()" would really clean out all data
structures, while "refresh" would rebuild them before the next run.

-John


-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html



Re: ANNOUNCE: MasonX::WebApp 0.01

2004-05-12 Thread Dave Rolsky
On Wed, 12 May 2004, John Siracusa wrote:

> > You must call clean_request_args() on the ApacheHandler object at the end of
> > the request, unless you are making a new ApacheHandler object for every
> > request. Otherwise bad things will happen.
> >
> > This is lame, so if someone thinks of a better way to do this, I'd be happy to
> > hear about it.
>
> In my massively more complicated (in both the good and bad senses of the
> word), but spiritually similar Mason-using WebApp framework, I do something
> like this:

[ much stuff snipped ]

I think one of the reasons you can do your stuff that way is that you are
using the Mason Interp object to dispatch to Mason, rather than the
ApacheHandler object.  Mason's ApacheHandler has no mechanism for being
handed a set of arguments, it insists on getting them itself (from an
Apache::Request or CGI object), which is a little annoying.

I hope to make ApacheHandler a little less self-contained in the next
major release (1.4), but for now I'm stuck with nasty hacks.


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/

-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html



Re: ANNOUNCE: MasonX::WebApp 0.01

2004-05-12 Thread John Siracusa
On 5/12/04 12:30 PM, Dave Rolsky wrote:
> On Wed, 12 May 2004, John Siracusa wrote:
>>> You must call clean_request_args() on the ApacheHandler object at the end of
>>> the request, unless you are making a new ApacheHandler object for every
>>> request. Otherwise bad things will happen.
>>> 
>>> This is lame, so if someone thinks of a better way to do this, I'd be happy
>>> to
>>> hear about it.
>> 
>> In my massively more complicated (in both the good and bad senses of the
>> word), but spiritually similar Mason-using WebApp framework, I do something
>> like this:
> 
> [ much stuff snipped ]
> 
> I think one of the reasons you can do your stuff that way is that you are
> using the Mason Interp object to dispatch to Mason, rather than the
> ApacheHandler object.  Mason's ApacheHandler has no mechanism for being
> handed a set of arguments, it insists on getting them itself (from an
> Apache::Request or CGI object), which is a little annoying.
> 
> I hope to make ApacheHandler a little less self-contained in the next
> major release (1.4), but for now I'm stuck with nasty hacks.

...which begs the question, why not use an interp in MasonX::WebApp instead
of trying to wedge in behind Mason's ApacheHandler?  After all, I think
that's the advice you originally gave me way back when... :)

-John


-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html



Re: ANNOUNCE: MasonX::WebApp 0.01

2004-05-12 Thread Dave Rolsky
On Wed, 12 May 2004, John Siracusa wrote:

> > I hope to make ApacheHandler a little less self-contained in the next
> > major release (1.4), but for now I'm stuck with nasty hacks.
>
> ...which begs the question, why not use an interp in MasonX::WebApp instead
> of trying to wedge in behind Mason's ApacheHandler?  After all, I think
> that's the advice you originally gave me way back when... :)

Don't listen to me!

Seriously, the ApacheHandler provides some useful functionality like
parsing arguments, configuration via httpd.conf, automatic header
handling, etc.


-dave

/*===
House Absolute Consulting
www.houseabsolute.com
===*/

-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html