first chunk o' docs
[catagits/Web-Simple.git] / lib / Web / Simple.pm
1 package Web::Simple;
2
3 use strict;
4 use warnings FATAL => 'all';
5
6 sub import {
7   strict->import;
8   warnings->import(FATAL => 'all');
9   warnings->unimport('syntax');
10   warnings->import(FATAL => qw(
11     ambiguous bareword digit parenthesis precedence printf
12     prototype qw reserved semicolon
13   ));
14   my ($class, $app_package) = @_;
15   $class->_export_into($app_package);
16 }
17
18 sub _export_into {
19   my ($class, $app_package) = @_;
20   {
21     no strict 'refs';
22     *{"${app_package}::dispatch"} = sub {
23       $app_package->_setup_dispatchables(@_);
24     };
25     *{"${app_package}::filter_response"} = sub (&) {
26       $app_package->_construct_response_filter($_[0]);
27     };
28     *{"${app_package}::redispatch_to"} = sub {
29       $app_package->_construct_redispatch($_[0]);
30     };
31     *{"${app_package}::default_config"} = sub {
32       my @defaults = @_;
33       *{"${app_package}::_default_config"} = sub { @defaults };
34     };
35     *{"${app_package}::self"} = \${"${app_package}::self"};
36     require Web::Simple::Application;
37     unshift(@{"${app_package}::ISA"}, 'Web::Simple::Application');
38   }
39 }
40
41 =head1 NAME
42
43 Web::Simple - A quick and easy way to build simple web applications
44
45 =head1 WARNING
46
47 This is really quite new. If you're reading this from git, it means it's
48 really really new and we're still playing with things. If you're reading
49 this on CPAN, it means the stuff that's here we're probably happy with. But
50 only probably. So we may have to change stuff.
51
52 If we do find we have to change stuff we'll add a section explaining how to
53 switch your code across to the new version, and we'll do our best to make it
54 as painless as possible because we've got Web::Simple applications too. But
55 we can't promise not to change things at all. Not yet. Sorry.
56
57 =head1 SYNOPSIS
58
59   #!/usr/bin/perl
60
61   use Web::Simple 'HelloWorld';
62
63   {
64     package HelloWorld;
65
66     dispatch [
67       sub (GET) {
68         [ 200, [ 'Content-type', 'text/plain' ], [ 'Hello world!' ] ]
69       },
70       sub () {
71         [ 405, [ 'Content-type', 'text/plain' ], [ 'Method not allowed' ] ]
72       }
73     ];
74   }
75
76   HelloWorld->run_if_script;
77
78 If you save this file into your cgi-bin as hello-world.cgi and then visit
79
80   http://my.server.name/cgi-bin/hello-world.cgi/
81
82 you'll get the "Hello world!" string output to your browser. For more complex
83 examples and non-CGI deployment, see below.
84
85 =head1 WHY?
86
87 While I originally wrote Web::Simple as part of my Antiquated Perl talk for
88 Italian Perl Workshop 2009, I've found that having a bare minimum system for
89 writing web applications that doesn't drive me insane is rather nice.
90
91 The philosophy of Web::Simple is to keep to an absolute bare minimum, for
92 everything. It is not designed to be used for large scale applications;
93 the L<Catalyst> web framework already works very nicely for that and is
94 a far more mature, well supported piece of software.
95
96 However, if you have an application that only does a couple of things, and
97 want to not have to think about complexities of deployment, then Web::Simple
98 might be just the thing for you.
99
100 The Antiquated Perl talk can be found at L<http://www.shadowcat.co.uk/archive/conference-video/>.
101
102 =head1 DESCRIPTION
103
104 The only public interface the Web::Simple module itself provides is an
105 import based one -
106
107   use Web::Simple 'NameOfApplication';
108
109 This imports 'strict' and 'warnings FATAL => "all"' into your code as well,
110 so you can skip the usual
111
112   use strict;
113   use warnings;
114
115 provided you 'use Web::Simple' at the top of the file. Note that we turn
116 on *fatal* warnings so if you have any warnings at any point from the file
117 that you did 'use Web::Simple' in, then your application will die. This is,
118 so far, considered a feature.
119
120 Calling the import also makes NameOfApplication isa Web::Simple::Application
121 - i.e. does the equivalent of
122
123   {
124     package NameOfApplication;
125     use base qw(Web::Simple::Application);
126   }
127
128 It also exports the following subroutines:
129
130   default_config(
131     key => 'value',
132     ...
133   );
134
135   dispatch [ sub (...) { ... }, ... ];
136
137   filter_response { ... };
138
139   redispatch_to '/somewhere';
140
141 and creates the $self global variable in your application package, so you can
142 use $self in dispatch subs without violating strict (Web::Simple::Application
143 arranges for dispatch subroutines to have the correct $self in scope when
144 this happens).
145
146 =head1 EXPORTED SUBROUTINES
147
148 =head2 default_config
149
150   default_config(
151     one_key => 'foo',
152     another_key => 'bar',
153   );
154
155   ...
156
157   $self->config->{one_key} # 'foo'
158
159 This creates the default configuration for the application, by creating a
160
161   sub _default_config {
162      return (one_key => 'foo', another_key => 'bar');
163   }
164
165 in the application namespace when executed. Note that this means that
166 you should only run default_config once - a second run will cause a warning
167 that you are override the _default_config method in your application, which
168 under Web::Simple will of course be fatal.
169
170 =head2 dispatch
171
172   dispatch [
173     sub (GET) {
174       [ 200, [ 'Content-type', 'text/plain' ], [ 'Hello world!' ] ]
175     },
176     sub () {
177       [ 405, [ 'Content-type', 'text/plain' ], [ 'Method not allowed' ] ]
178     }
179   ];
180
181 The dispatch subroutine calls NameOfApplication->_setup_dispatchables with
182 the subroutines passed to it, which then create's your Web::Simple
183 application's dispatcher from these subs. The prototype of the subroutine
184 is expected to be a Web::Simple dispatch specification (see
185 L</DISPATCH SPECIFICATIONS> below for more details), and the body of the
186 subroutine is the code to execute if the specification matches. See
187 L</DISPATCH STRATEGY> below for details on how the Web::Simple dispatch
188 system uses the return values of these subroutines to determine how to
189 continue, alter or abort dispatch.
190
191 Note that _setup_dispatchables creates a
192
193   sub _dispatchables {
194     return (<dispatchable objects here>);
195   }
196
197 method in your class so as with default_config, calling dispatch a second time
198 will result in a fatal warning from your application.
199
200 =head2 response_filter
201
202   response_filter {
203     # Hide errors from the user because we hates them, preciousss
204     if (ref($_[1]) eq 'ARRAY' && $_[1]->[0] == 500) {
205       $_[1] = [ 200, @{$_[1]}[1..$#{$_[1]}] ];
206     }
207     return $_[1];
208   };
209
210 The response_filter subroutine is designed for use inside dispatch subroutines.
211
212 It creates and returns a response filter object to the dispatcher,
213 encapsulating the block passed to it as the filter routine to call. See
214 L</DISPATCH STRATEGY> below for how a response filter affects dispatch.
215
216 1;
217
218 1;