Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Yet Another Web Framework

by philcrow (Priest)
on May 10, 2006 at 20:17 UTC ( [id://548551]=perlmeditation: print w/replies, xml ) Need Help??

SUMMARY

While the world may need a new web framework about as badly as it needs a new conflict in the Middle East, we feel the urge to share ours.

Gantry is the third generation of a web framework, which has been running many of our internal and external sites for years, but which is now making its debut as an open source project (under the same license as Perl).

Check it out at http://www.usegantry.org.

Gantry features:

  • Transparent URL dispatching.
  • Flexibility in deployment:
    • Serve the same app from different servers.
    • Serve multiple instances of the same app on the same server.
    • Switch from CGI to mod_perl without code changes.
    • Change all app configuration without code changes even in CGI.
  • Pick your own architecture: MVC, MC, VC, C, etc. take your pick.
  • Emphasis on support for cron jobs and other batch processing.
  • Simple CRUD with AutoCRUD.
  • Advanced CRUD so flexible it doesn't even care if you use a database.
  • Bigtop generation and safe regeneration of code, SQL schemas, etc.
  • Clean factoring of engines: mod_perl 1, mod_perl 2, CGI, FastCGI.
  • Access to your engine's specifics (like the Apache request object).
  • Complete configuration control and flexibility through Gantry::Conf.
  • Simple stand alone server for testing and app deployment.

Why the Name?

A gantry is a scaffold for building and servicing rockets. Rails may be nice, but rockets are faster and have more destinational flexibility.

Another more practical meaning for gantry in our context is the structure which holds signs or signals over a road or railroad. This is a permanent structure often outlasting the signs initially placed on it.

Gantry principles:

  • Explicit is better than implicit
  • A sysadmin covering for us on a weekend should find things intuitive
  • It's your app, you make the decisions
  • Web apps are usually all about the data
  • A framework should do more than half the work without your help
  • A framework should get out of the way when it can't help

Don't think of Gantry as a scaffold or falsework. Think of it as a structural support which will outlive your app.

Gantry was developed at Sunflower Broadband (a cable/internet service/phone provider in Lawrence, KS).

EXAMPLE

Here is the required world greeter to show the simplest Gantry app.
First, we need the operative code (which should be stored in HiWorld.pm):
package HiWorld; use strict; use warnings; use base 'Gantry'; sub do_main { my $self = shift; return "Hello, Rob"; } 1;
Then we need to deploy the app. We have several choices. The first and easiest choice is a stand alone test server. It might look like this:
#!/usr/bin/perl use strict; use Gantry::Server; use lib '/home/myhome/lib'; use HiWorld qw{ -Engine=CGI -TemplateEngine=Default }; my $cgi = Gantry::Engine::CGI->new( { locations => { '/' => 'HiWorld' } } ); my $port = shift || 8080; my $server = Gantry::Server->new( $port ); $server->set_engine_object( $cgi ); $server->run();
You can execute this, giving it an alternate port number if you don't want 8080.

Don't let the appearance of CGI in the above fool you. This is a persistent web server which is quite fast. It does use the Gantry CGI engine internally, but it doesn't spawn any processes.

See Gantry::Docs::QuickStart for additional discussion, including other ways to deploy an app (like actual CGI or our favorite mod_perl). Then move on to Gantry::Docs::Tutorial.

LONG FORM

What we want:

Our business relies on delivering apps to our staff and to our customers. Gantry is designed to meet the needs of a company like ours. In particular, we have these hot button issues:

Configuration

We have lots of applications. While we traditionally configured them via PerlSetVars in our httpd.conf, that system breaks down. First, we sometimes deploy the same application on different servers (say to deliver it to customers and to customer support staff). We want those deployments of the same application to share configuration. Second, we sometimes deploy multiple instances of the same application (say to deliver the same product to two divisions of the company). We often deploy these in the same apache instance. We want them to be able to share their common configuration while allowing them to have differences (like database connection information). Third, we almost always have some batch processing (think cron jobs) associated with our apps. We want them to use the same configuration as the web app.

So, the boss designed Gantry::Conf to solve all of the problems we were having with our old configuration scheme. See Configuration Flexibility or Gantry::Conf::Tutorial for details, but allow me to summarize. With a single file on each box, you can describe all the app instances which run on that box. When describing each instance, you may specify multiple flat files of conf info. In addition, you may specify any url lwp understands to retrieve conf from foreign machines (yes you need a security plan). Finally, you may also put config variables directly into the one-stop conf file to be shared by multiple app instances.

Simply calling one method, with your instance name, returns your conf, no matter where it came from.

And the best part is: You don't have to use Gantry to use Gantry::Conf.

Straightforward Dispatching

We want a scheme so simple that a sysadmin, fresh from a roaring party, can cover for us while we are out of town. This means he must be able to take a broken url reported by some user and quickly find the code connected to it. To this end Gantry uses a simple dispatching scheme with few tricks.

While no dispatching scheme capable of supporting complex apps is trivial, ours is pretty straightforward. Even our Python loving admin understands it.

Flexibility

Some people want a framework which makes all choices for them. If you are one of those people, Gantry is not for you. We don't want to force a single way of doing any given thing into the framework. We want to make it easy to use the tools that spring to mind for the task at hand, regardless of whose mind contains the spring.

For example, one of our developers taught us to like the idea of postpending method arguments onto the url. We then shift them in to lexical variables. You might prefer to use a query string. Take your pick, Gantry supports both with easy syntax.

As another example, if you have standard CRUD work to do, you can use Gantry::Plugins::AutoCRUD. This makes a lot of assumptions, but does all the work (except defining the form and its validation). If you need more control, there is Gantry::Plugins::CRUD. It's so flexible that it doesn't even care if you use a database. Yet it still removes the tedium of form validation.

Code Generation

We are demanding. We want a lot from our tools including our generators. Further, we have a philosophy (at least I do) about web delivered apps. Most of them are centered around the data they manage. Hence, building a new one is primarily an exercise in data modeling. Fred Brooks said this well in The Mythical Man-Month:
Show me your flowchart and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won't usually need your flowchart; it'll be obvious.
This led me to develop bigtop: a language for describing data models. We already have SQL to specify the names, relationships, and format of data. But, for me, this is not enough. I want a single place to define the columns in a table in full detail. This includes not only the name and SQL type, but what its label should be for the user, how wide the input box should be on the input form, whether the field is required, what constraints should be applied during validation, etc. Bigtop allows me to describe all this and a lot more.

Further, when my data model changes, as it always seems to, bigtop can safely regenerate the app, with the changes but without overwriting custom code I've written.

The main drawback to bigtop is learning its syntax, which while simple in structure is quite rich in keywords. This led to the development of tentmaker, a web delivered editor for bigtop files. It comes with a built-in skeleton to get you started.

I'll have more to say about bigtop in a later meditation.

Phil

Replies are listed 'Best First'.
Re: Yet Another Web Framework
by gellyfish (Monsignor) on May 11, 2006 at 13:22 UTC

    I think you're mistaken, this can't be a proper framework as I don't think it has been forked, started a flamewar or been proclaimed as the Greatest Since Perl 5 yet. But you're getting there with the name, it has the right combination of almost possibly making sense in the context and pure nonsense that epitomizes the genre.

    /J\

Re: Yet Another Web Framework
by Anonymous Monk on May 11, 2006 at 13:07 UTC

    Just installed 3.30 from tarball. It's not available on my CPAN mirror yet.

    I'm going to try out the quick start and tutorial, more about that later. But for now, some comments about the installation, from back to front.

    ---------------------------------------------------------------------- +---------- Web Directory ---------------------------------------------------------------------- +---------- dev : /home/httpd/html/gantry prod : /home/httpd/html/gantry tim : /home/tkeefer/httpd/html/gantry Web Directory [dev,prod,tim]?

    This isn't explained anywhere. You really need a README and INSTALL file in the root of the archive which covers this. I got past it by guessing the intention. I made a directory /usr/local/apache2/htdocs/gantry, chmodded it 777, and gave the directory name as answer to the question. It worked and now I have some templates and styles installed there.

    t/01pod..........................skipped all skipped: set TEST_POD to enable this test t/01podcoverage..................skipped all skipped: set TEST_POD to enable this test

    I know why you skip by default, you rascals! ;) I realise POD is boring and low priority, but take this friendly reminder here that you should get 100% here, some day.

    # Do you want to run Gantry Auth application tests [no]? y # Enter database connection string [dbi:Pg:dbname=master_auth]? # Enter database user [apache]? foobar # Enter database password []? # Failed test 'expected 200, received 1 = {}; for /site/users' # in t/auth/01run.t at line 71. # /site/users # DBI connect('dbname=master_auth','',...) failed: FATAL: role "root" + does not exist # at /usr/local/src/Gantry-3.30/blib/lib/Gantry/Utils/ModelHelper.pm +line 76 t/auth/01run.....................NOK 2

    This is just great, asks me for a db user name, but uses root anyway.

    I didn't quite know what this is supposed to accomplish in detail, so I just created the db master_auth with user foobar before pressing enter for the first question. It failed, as you can see above. For the next run, I skipped just dbi testing.

    Checking prerequisites... - ERROR: HTML::Prototype is not installed - ERROR: Data::Page is not installed - ERROR: Class::DBI::Sweet is not installed - ERROR: Hash::Merge is not installed - ERROR: File::Copy::Recursive is not installed - ERROR: Template is not installed - ERROR: Class::DBI is not installed - ERROR: Data::FormValidator is not installed

    Argh, quite a lot. Template-Toolkit was a real bitch to install with its many questions and test #7 of t/gd.t mysteriously failing with just a couple of bytes difference. Does anyone else notice that (hint: make test TEST_VERBOSE=1)? I converted those long hex strings into binary, but it didn't result in a valid PNG file. So I resolved that it can't probably matter and just forced the installation.

      Thanks for your comments. We are discussing them and will take action to make things cleaner, clearer, and generally better for newcomers.

      In particular, we had lots of pod, but hadn't tried testing it. Of course, there were broken tags and the like. There were also some undocumented methods. All of that has been repaired. The svn version now passes all pod and podcoverage tests (though we probably won't enable them by default).

      We are also interested in reducing the prereq list, which is really more a list of suggestions than requirements. But, we will have to rework some tests to make the modules optional during testing. That will take a little time.

      Phil

Re: Yet Another Web Framework
by blazar (Canon) on May 11, 2006 at 09:33 UTC
      Thanks for the section placement advice. My mind only remembered conference information and pointers to media stories in Perl News.

      Phil

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://548551]
Approved by Corion
Front-paged by Argel
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (8)
As of 2024-04-23 13:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found