File Coverage

blib/lib/Web/MREST.pm
Criterion Covered Total %
statement 40 63 63.4
branch 3 20 15.0
condition 0 6 0.0
subroutine 12 12 100.0
pod 2 2 100.0
total 57 103 55.3


line stmt bran cond sub pod time code
1             # *************************************************************************
2             # Copyright (c) 2014-2015-2015, SUSE LLC
3             #
4             # All rights reserved.
5             #
6             # Redistribution and use in source and binary forms, with or without
7             # modification, are permitted provided that the following conditions are met:
8             #
9             # 1. Redistributions of source code must retain the above copyright notice,
10             # this list of conditions and the following disclaimer.
11             #
12             # 2. Redistributions in binary form must reproduce the above copyright
13             # notice, this list of conditions and the following disclaimer in the
14             # documentation and/or other materials provided with the distribution.
15             #
16             # 3. Neither the name of SUSE LLC nor the names of its contributors may be
17             # used to endorse or promote products derived from this software without
18             # specific prior written permission.
19             #
20             # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21             # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22             # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23             # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24             # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25             # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26             # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27             # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28             # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29             # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30             # POSSIBILITY OF SUCH DAMAGE.
31             # *************************************************************************
32              
33             package Web::MREST;
34              
35 22     22   208162 use 5.012;
  22         81  
36 22     22   107 use strict;
  22         47  
  22         447  
37 22     22   105 use warnings;
  22         46  
  22         632  
38              
39 22     22   121 use App::CELL qw( $CELL $log $meta $core $site );
  22         39  
  22         2990  
40 22     22   154 use App::CELL::Test qw( _touch );
  22         54  
  22         967  
41 22     22   289 use Data::Dumper;
  22         56  
  22         864  
42 22     22   220 use File::ShareDir;
  22         46  
  22         773  
43 22     22   579 use Log::Any::Adapter;
  22         755  
  22         208  
44 22     22   589 use Params::Validate qw( :all );
  22         37  
  22         3401  
45             #use Try::Tiny;
46 22     22   652 use Web::Machine;
  22         181430  
  22         12007  
47              
48              
49              
50              
51             =head1 NAME
52              
53             Web::MREST - Minimalistic REST server
54              
55              
56              
57              
58             =head1 VERSION
59              
60             Version 0.288
61              
62             =cut
63              
64             our $VERSION = '0.288';
65              
66              
67             =head2 Development status
68              
69             L<Web::MREST> is currently in "Alpha - feature freeze". There are almost
70             certainly bugs lurking in the code, but all features have been implemented.
71              
72              
73              
74              
75             =head1 SYNOPSIS
76              
77             To take this module for a spin, execute this command:
78              
79             $ mrest Web-MREST Web::MREST::Dispatch
80              
81             Leave this running, and from another console start the command-line client:
82              
83             $ mrest-cli
84              
85             In the CLI client, type e.g.
86              
87             Web::MREST::CLI::Parser> get /
88              
89             A 'GET' request will be sent for the root resource and the CLI client
90             will display a representation of the response.
91              
92             A similar result can be obtained using C<curl>:
93              
94             curl -v http://localhost:5000/ -X GET -H "Content-Type: application/json"
95              
96              
97              
98              
99             =head1 DESCRIPTION
100              
101             MREST stands for "minimalistic" or "mechanical" REST server. (Mechanical because
102             it relies on L<Web::Machine>.)
103              
104             L<Web::MREST> provides a fully functional REST server that can be started
105             with a simple command. Without modification, the server provides a set of
106             generalized resources that can be used to demonstrate how the REST server
107             works, or for testing.
108              
109             Developers can use L<Web::MREST> as a platform for implementing their own
110             REST servers, as described below. L<App::Dochazka::REST> is a "real-world"
111             example of such a server.
112              
113             For an introduction to REST and Web Services, see
114             L<Web::MREST::WebServicesIntro>.
115              
116              
117              
118             =head1 RFC2616 AS A STATE MACHINE
119              
120             RFC2616 is, of course, the HTTP 1.1 standard - not a state machine. But
121             the authors of "Web Machine" (which was originally implemented in Erlang) had a
122             neat idea to represent it as a state machine and use this to implement a server
123             for providing web services.
124              
125             L<Web::Machine> is, of course, the Perl port of Web Machine.
126              
127             L<Web::MREST> relies on L<Web::Machine> to implement RFC2616. L<Web::MREST>
128             can be thought of as an additional abstraction layer over L<Web::Machine>.
129              
130             By itself, L<Web::Machine> is not a server. It does not listen on a port, for
131             example. Instead, it is designed to work (via L<Plack>) with a
132             L<PSGI>-compliant web server.
133              
134             The web server hands incoming requests over to L<Web::Machine>, which runs the
135             requests through its state machine. (The L<Web::Machine> authors refer to the
136             state machine as "the FSM.") The best way to grasp the state machine is to
137             envision it as a flow-chart. At each "decision node" of the flow-chart - where
138             flow can go in one of two directions - L<Web::Machine> calls the method
139             corresponding to that node. Each node is designated by a letter and a number:
140             e.g. F7, O18, etc.
141              
142             The flow-chart implemented by the FSM can be found L<here|http://...> - you are
143             encouraged to have that open for reference while reading this documentation
144             and implementing your REST server.
145              
146              
147              
148              
149             =head1 SERVER STARTUP AND INHERITANCE SCHEME
150              
151              
152             =head2 Standalone mode
153              
154             As stated above, L<Web::MREST> is capable of operating independently. To try
155             it out, start up the server like this:
156              
157             $ mrest-standalone
158              
159             And then point your browser to
160              
161             http://localhost:5000
162              
163             If you look inside the C<mrest-standlone> script, you will see that it is
164             just a wrapper for the C<mrest> script, which takes two mandatory options. The
165             first, C<--distro>, is the name of the distribution in whose sharedir it should
166             look for configuration files. The second, C<--module>, is the name of the
167             application's resource module, i.e. the ultimate module in the chain of
168             inheritance.
169              
170             In standalone mode, the actual command that is run is:
171              
172             mrest --distro=Web::MREST --module=Web::MREST::Dispatch
173              
174             which causes the chain of inheritance to be built up as follows:
175              
176             =over
177              
178             =item C<bin/mrest>
179              
180             calls C<< Web::Machine->new >>; the L<Web::Machine> object is blessed into L<Web::MREST::Dispatch>
181              
182             =item L<Web::MREST::Dispatch>
183              
184             inherits from L<Web::MREST::Entity>
185              
186             =item L<Web::MREST::Entity>
187              
188             inherits from L<Web::MREST::Resource>
189              
190             =item L<Web::MREST::Resource>
191              
192             inherits from L<Web::Machine::Resource>
193              
194             =back
195              
196             When you browse to C<http://0:5000> in standalone mode, you get a list of the
197             sample REST resources that are available. For more information on these, see
198             C<config/dispatch_Config.pm>.
199              
200              
201             =head2 With your application
202              
203             Starting the server with your application is the same as described in
204             L<"Standalone mode">, above, except that you replace C<Web-MREST> with the name
205             of your distribution and C<Web::MREST::Dispatch> with the name of your ultimate
206             resource module.
207              
208             $ mrest YourApp-MREST YourApp::MREST::Dispatch
209              
210             For example, here we are starting the server with the distribution
211             C<YourApp-MREST>, which is presumed to implement a chain of inheritance
212             similar to L<Web::MREST>'s, i.e.:
213              
214             Web::MREST -> YourApp::MREST::Resource -> YourApp::MREST::Dispatch
215              
216             Thanks to this arrangement, the application developer can customize
217             L<Web::MREST> - i.e., not only providing her own resources and handlers,
218             but even altering how the state machine operates, if necessary - by providing
219             her own chain of inheritance and overriding various methods within it.
220              
221              
222             =head3 Recapitulation
223              
224             Since the above is quite important, let's go over it again:
225              
226             The L<Web::MREST> documentation will always refer to your application either
227             as the "application" or as C<YourApp>. The application should take the form
228             of a Perl distribution, which should have:
229              
230             =over
231              
232             =item * a distribution sharedir
233              
234             =item * a resource module, C<YourApp::Resource>.
235              
236             =item * a dispatch module, C<YourApp::Dispatch>
237              
238             =back
239              
240             For now, just think of these three components as "black boxes". We will
241             cover their contents later.
242              
243             The server (i.e. your application), is started by executing the C<mrest>
244             executable with the name of your application's distribution and the name of its
245             dispatch module, which should be the ultimate module in the chain of
246             inheritance.
247              
248             $ perl mrest YourApp YourApp::Dispatch
249              
250             Under the hood the startup script, which can be reviewed at C<bin/mrest>,
251             does essentially this:
252              
253             use Web::Machine;
254              
255             Web::Machine->new(
256             resource => 'YourApp::Dispatch',
257             )->to_app;
258              
259             There are two key points concerning the L<Web::Machine> object constructed by
260             call to C<< Web::Machine->new >>:
261              
262             =over
263              
264             =item 1. the object is blessed into C<YourApp::Dispatch>
265              
266             =item 2. the object is a L<Plack> application
267              
268             =back
269              
270              
271              
272             =head1 INHERITANCE SCHEME
273              
274             As seen in the previous section, C<YourApp> inherits from
275             L<Web::MREST> via a chain of inheritance. Here is the chain implemented by L<Web::MREST>:
276              
277            
278             -> Web::MREST::Dispatch
279             -> Web::MREST::Entity
280             -> Web::MREST::Resource
281             -> Web::Machine::Resource
282             -> Plack::Component
283              
284             Assuming L<YourApp> has its authentication and authorization routines
285             in L<YourApp::Resource> and its resource definitions and handlers in
286             L<YourApp::Dispatch>, the chain for L<YourApp> would look like this:
287              
288             -> YourApp::Dispatch
289             -> YourApp::Resource
290             -> Web::MREST::Entity
291             -> Web::MREST::Resource
292             -> Web::Machine::Resource
293             -> Plack::Component
294              
295             (In other words, L<YourApp::Dispatch> and L<YourApp::Resource> replace
296             L<Web::MREST::Dispatch>, which is just a demo.)
297              
298             When L<Web::Machine> reaches a given node in the FSM, it calls the
299             corresponding method on that L<Web::Machine> object. Since the object is
300             blessed into C<YourApp::Dispatch>, that module is where Perl will
301             start to look for the method.
302              
303             If the method is not found at the lowest level, Perl follows the chain of
304             inheritance "upward". The highest level, L<Plack::Component>, is shown only for
305             completeness - L<Web::MREST::Resource> and L<Web::MREST::Entity> implement
306             all the methods that your resource module might (or should) want to override.
307              
308             Readers who are not well-versed in writing Perl applications that use
309             inheritance are referred to the fine Perl manuals such as C<perlootut>.
310              
311              
312              
313             =head1 STATE MACHINE INTRODUCTION
314              
315             At this point we have enough background information to begin to grasp the state
316             machine. (Instead of writing "state machine" we will follow the L<Web::Machine>
317             convention of referring to it as the "FSM".) This section presents selected
318             features and nodes of the FSM, how L<Web::MREST> implements them, and how to
319             use them. The discourse proceeds in the order in which the methods are called
320             when an HTTP request enters the FSM. We can envision these method calls as
321             decision nodes of a flow-chart, or "cogs" of the FSM.
322              
323             And we needn't just imagine the flow-chart - it actually exists and can be
324             downloaded from L<...>. If you want to understand how L<Web::Machine> and
325             L<Web::MREST> work, this document is of fundamental importance. Hereinafter
326             it will be referred to as "the FSM diagram".
327              
328             As you can see in the FSM diagram, each FSM cog has a code like C<B6>, for ease
329             of reference.
330              
331              
332              
333             =head1 POLICIES AND FEATURES
334              
335             L<Web::Machine> implements the FSM, and that's all it does. In particular, it
336             imposes no policies on distributions that use it. By taking this approach,
337             L<Web::Machine> maximizes its range of potential uses.
338              
339             Powerful as it is, L<Web::Machine> can be confusing to use. When I started
340             writing my first application based on it, I found myself wanting an
341             intermediate module between my application and L<Web::Machine> - something that
342             would make L<Web::Machine> a little more friendly.
343              
344             L<Web::MREST> is that module. It builds on L<Web::Machine> in an effort to
345             provide certain additional features. Inevitably, this means imposing some
346             policies (i.e., limitations) on users. To me that seems like an acceptable
347             trade-off.
348              
349              
350             =head2 Path dispatch
351              
352             A key part of any web application is "path dispatch" (i.e. URI translation),
353             which answers the question: "how are URIs mapped to resources?"
354              
355             Although L<Web::Machine> provides a way to specify handlers for various media
356             types that may appear in request and response entities, it provides no
357             way of getting from the URI to the handler. L<Web::MREST> bridges this gap
358             by providing a system of resource definitions (see L<"Resource definitions">,
359             below).
360              
361             The definition of each resource specifies the URI-to-resource mapping and
362             provides the name of the resource's handler method. Internally, L<Web::MREST>
363             uses a single L<Path::Router> object to parse URIs.
364              
365             Before any URIs can be parsed, this L<Path::Router> object must be initialized.
366             This is done in L<Web::MREST::Resource>, in the C<service_available> method.
367             That method checks the scalar variable that is supposed to contain the
368             L<Path::Router> object and, if needed, calls the C<init_router> method to
369             initialize it.
370              
371             In the L<Web::MREST> demo application, C<init_router> is implemented in
372             L<Web::MREST::Dispatch>.
373              
374              
375             =head2 Resource handlers
376              
377             The L<Web::Machine> documentation mentions "handlers" but doesn't go into
378             any detail on how to write them. L<Web::MREST> not only provides some working
379             resource handlers, but also implements a paradigm for writing them.
380              
381             In this paradigm, the handler is called as a method, just like any of the other
382             methods in the chain of inheritance. (To avoid namespace issues, it is
383             recommended that handler method names start with C<handler_>.) The name of the
384             method is specified in the resource definition.
385              
386             The handler method is called twice - in other words, there are two passes. In
387             the first pass, the handler is called with the argument C<1> (scalar value) and
388             is expected to return a boolean value indicating whether the resource exists.
389              
390             In the second pass, indicated by the argument C<2> (scalar value), the handler
391             is expected to return a C<App::CELL::Status> object. This object (rendered in
392             JSON) becomes the response entity unless overrided by a declared status (see
393             C<mrest_declare_status> in L<Web::MREST::Resource>.
394              
395             B<N.B.:> The request entity is not available to the handler (via
396             C<$self->context->{request_entity}> until the second pass!
397              
398              
399             =head2 Status objects
400              
401             As mentioned in the previous section, L<App::CELL::Status> objects are returned
402             by resource handlers. Not only that - L<Web::MREST> tries its best to I<always>
403             return an L<App::CELL::Status> object in the response entity.
404              
405             Actually, it is not the object itself that is returned, but a JSON
406             representation of its underlying data structure. From this, the object can
407             easily be reconstituted on the client side by doing
408              
409             my $status = $JSON->decode( $response_entity );
410             bless $status, 'App::CELL::Status';
411              
412             For more on what status objects can do, see L<App::CELL::Status>, L<App::CELL>,
413             and L<App::CELL::Guide>.
414              
415              
416             =head2 Error statuses
417              
418             L<Web::Machine> always tries to return the proper HTTP status code in the
419             response. The application developer will likely need to "force" a code in
420             certain cases. For example, the request may be "malformed" in a way that is
421             not discoverable until the handler runs. Or, caught exceptions may need to be
422             exposed to the client with C<500 - Internal Error>.
423              
424             Also, the RFC says
425              
426             . . . the server SHOULD include an entity containing an explanation of the
427             error situation, and whether it is a temporary or permanent condition.
428              
429             Clearly, then, a mechanism is needed for providing such explanations and
430             indicating whether the error is temporary or permanent. And that mechanism
431             should enable an arbitrary status code to be declared.
432              
433             By itself, L<Web::Machine> does not really provide such a mechanism. What it
434             does provide is a mechanism for "forcing" an arbitrary status code (e.g. C<404
435             - Not Found>) by returning a scalar reference. This mechanism has two
436             disadvantages:
437              
438             =over
439              
440             =item it is only available at certain junctions of the FSM
441              
442             I wanted a way to "declare" a status code at any point and be certain that
443             L<Web::Machine> won't change it later on.
444              
445             =item there is no obvious way to provide an explanation of the error
446              
447             L<Web::Machine> considers this an implementation detail.
448              
449             =back
450              
451             Hence, L<Web::MREST> provides the C<mrest_declare_status> method. To learn
452             how to call it and how it works, see L<Web::MREST::Resource>.
453              
454              
455              
456             =head1 THE FINE STATE MACHINE
457              
458             In this section we take a detailed look at the FSM by considering some common
459             scenarios. For our purposes these are C<GET>, C<POST>, C<PUT>, and C<DELETE>
460             requests. Handling can differ according to whether or not a C<POST> creates a
461             new resource and whether or not the resource is determined to exist.
462              
463             =head2 Part One (sanity checks and information gathering)
464              
465             The first few cogs are executed, in the same order, on all requests regardless
466             of method. They can be thought of both as a set of sanity checks and as an
467             information-gathering process.
468              
469              
470             =head3 C<service_available> (B13)
471              
472             The first method call is C<service_available>, which is implemented by
473             L<Web::MREST::Resource> and should I<not> be implemented by your application,
474             because it calls C<init_router> to ensure that all the resource definitions are
475             loaded and the L<Path::Router> singleton is properly initialized.
476              
477             This is not really a limitation, however. Whatever code you need to run here
478             can be placed in a method called C<mrest_service_available>, which should
479             return a boolean value (i.e. 1 or 0), which determines the return value from
480             the method.
481              
482             If the service really isn't available, you can return false, which will trigger
483             a C<503 Service Not Available> response. Before returning you should do:
484              
485             $self->mrest_declare_status( explanation => '...', permanent => 0 );
486              
487             to provide an explanation of what is going on.
488              
489             For details, see the C<t/503-Service-Unavailable.t> unit test.
490              
491              
492             =head3 C<known_methods> (B12)
493              
494             Returns the list of supported ("known") methods in
495             C<< $site->MREST_SUPPORTED_HTTP_METHODS >>. If the request method is not
496             in that list, a C<501 Not Implemented> response is returned along with
497             an explanation that the method requested is not supported.
498              
499             If this behavior is not appropriate, the method can be implemented by the
500             application.
501              
502              
503             =head3 C<uri_too_long> (B11)
504              
505             If the request URI is longer than the value set in the C<MREST_MAX_LENGTH_URI> site parameter,
506             the client will receive a C<414 Request URI Too Long> response.
507              
508             To override this behavior, provide your own C<uri_too_long> routine in your
509             resource module.
510              
511             This functionality is demonstrated by the C<t/414-Request-URI-Too-Long.t> unit.
512              
513              
514             =head3 C<allowed_methods> (B10)
515              
516             "Is the method allowed on this resource?"
517              
518             This next routine is where things start to get complicated. According to the
519             L<Web::Machine::Resource
520             documentation|https://metacpan.org/pod/Web::Machine::Resource#allowed_methods>,
521             we are expected to respond with a list of methods allowed on the resource. To
522             assemble such a list, we must first answer two questions:
523              
524             =over
525              
526             =item 1. Have the resource definitions been loaded?
527              
528             =item 2. Does the URI match a known resource?
529              
530             =back
531              
532             After the server starts, the first time this method is called triggers a
533             call to the C<init_router> method, which populates the C<$resources> package
534             variable in C<Web::MREST::InitRouter> with all the resource definitions.
535             This is explained in detail in L<"Resource definitions">. This takes care of
536             the first question.
537              
538             The second question is answered by C<Path::Router>. Once the request has
539             been associated with a known resource, completing our task becomes a matter of
540             getting and returning the set of methods for which the resource is defined.
541              
542              
543             =head3 C<malformed_request> (B9)
544              
545             A true return value from this method triggers a "400 Bad Request" response
546             status. RFC2616 does not stipulate exactly what constitutes a bad request.
547             We already (in allowed_methods) took care of the case when the URI
548             fails to match a known resource, and that includes applying any C<validations>
549             properties from the resource definition.
550              
551             So, in this method (or your overlay) we take the "next step" (whatever that is)
552             in vetting the request. Keep in mind that this method is called before
553             the resource handler. If you have any sanity checks you wish to apply _after_
554             the URI is matched to a resource but _before_ the resource handler fires, this
555             is the place to put them.
556              
557             If you would like to keep L<Web::MREST>'s implementation of this method
558             (which, for example, pushes the Content-Length and Content-Type information
559             onto the context) and add your own logic, you can put it in
560             C<mrest_malformed_request> instead of overriding C<malformed_request> itself.
561              
562             If you intend to return false from this method you should first do this:
563              
564             $self->mrest_declare_status( explanation => '...' );
565              
566             to ensure that an explanation is included with the 400 response.
567              
568              
569             =head3 C<is_authorized> (B8)
570              
571             In my mind, "authentication" is the process of determining who the user
572             is, and "authorization" determines if the user is allowed to do what she
573             is asking to do. However, RFC2616 does not make such a clear distinction.
574              
575             For that reason, it is left to the application to implement this method
576             if needed.
577              
578              
579             =head3 C<forbidden> (B7)
580              
581             The same thoughts as expressed under C<is_authorized>, above, apply to
582             this method as well.
583              
584              
585             =head3 C<valid_content_headers> (B6)
586              
587             This is where you vet the C<Content-*> headers in the request. If the
588             request contains any invalid C<Content-*> headers (i.e., if the '*' part
589             does not appear in << $site->MREST_VALID_CONTENT_HEADERS >>),
590             a 501 will be generated.
591              
592             The content headers are passed to the method in a L<Hash::MultiValue>
593             object.
594              
595              
596             =head3 C<known_content_type> (B5)
597              
598             If the C<Content-Type> header is relevant - i.e., if this is a PUT or
599             POST request and if there is a request entity - check it against
600             << $site->MREST_SUPPORTED_CONTENT_TYPES >>.
601              
602              
603             =head3 C<valid_entity_length> (B4)
604              
605             A simple routine that compares the entity length (in bytes) with the
606             maximum set in C<< $site->MREST_MAX_LENGTH_REQUEST_BODY >>.
607              
608              
609             =head3 C<options> (B3)
610              
611             If your application needs to support the C<OPTIONS> method, you should
612             implement this yourself - otherwise, ignore it.
613              
614              
615             =head2 Part Two (content negotioation)
616              
617             The HTTP standard provides some complicated logic to enable clients
618             and servers to "negotiate" the format (media type), language, encoding,
619             etc. in which content will be passed back and forth. Here in the L<Web::MREST>
620             documentation we gloss over this complexity and focus only on the media type.
621             However, L<Web::Machine> includes methods for handling all the content
622             negotiation decision nodes and the application developer is free to take
623             advantage of them.
624              
625             That said, L<Web::MREST> itself provides JSON handlers for both the request and
626             the response entities, and should be fully UTF-8 clean. Hopefully, this will
627             save application developers some work. (For more information, see L<"STATUS
628             OBJECTS AND ERROR HANDLING">.)
629              
630             The following subsections detail the principal content negotiation methods.
631              
632             =head3 C<content_types_provided>
633              
634             As the L<Web::Machine::Resource> documentation states, this method must be
635             implemented (i.e., by the application) - otherwise, "your resource will not be
636             able to return any useful content".
637              
638             Quoting further: "This should return an ARRAY of HASH ref pairs where the key
639             is the name of the media type and the value is a CODE ref (or name of a method)
640             which can provide a resource representation in that media type."
641              
642             The implementation provided by L<Web::MREST> allows clients to specify (via
643             an C<Accept> header) one of two media types:
644              
645             =over
646              
647             =item C<text/html>
648              
649             Since it is the first hashref pair of the two, it is the default. That means
650             if the incoming request does not have an C<Accept> header, the handler
651             specified for C<text/html> will be called to generate the response entity.
652              
653             =item C<application/json>
654              
655             This is the media type that L<Web::MREST> was written to support, both in
656             request entities and in response entities. However, there is nothing preventing
657             you as the application developer from specifying handlers for other media types.
658              
659             =back
660              
661             If the request includes an C<Accept> header, but none of the media types
662             specified in it are found in C<content_types_provided>, L<Web::Machine> will
663             generate a C<406 Not Acceptable> response. (Unfortunately, there is no easy way
664             for L<Web::MREST> or the application to know in advance that this error will be
665             triggered, so it will be returned "bare" - i.e., without any explanatory
666             response entity.)
667              
668             In the normal case when an acceptable handler exists, it will be called to
669             generate the response - in other words, whatever is returned by the chosen
670             handler becomes the response entity, unless an error occurs inside the handler.
671             In that case, the handler should return a reference to a scalar value
672             (e.g., \400), which L<Web::Machine> will interpret as an HTTP response code.
673             See L<"STATUS OBJECTS AND ERROR HANDLING">.
674              
675             For more on response entity generation, see the sections dedicated to the
676             various HTTP methods (L<"GET">, L<"PUT">, L<"POST">, L<"DELETE">), below.
677              
678              
679             =head3 C<content_types_accepted>
680              
681             When the client sends C<PUT> or C<POST> requests, it will typically provide a
682             'Content-Type' header specifying the media type of the bytes it is sending in
683             the request body. This content type is compared with the media types returned
684             by this method. If there is no match, L<Web::Machine> returns a C<415
685             Unsupported Media Type> error response. (Unfortunately, there is no easy way
686             for L<Web::MREST> or the application to know in advance that this error will be
687             triggered, so it will be returned "bare" - i.e., without any explanatory
688             response entity.)
689              
690              
691             =head3 Other methods
692              
693             For handling character sets, encodings, and languages, L<Web::Machine> provides
694             a number of other content negotiation methods:
695              
696             =over
697              
698             =item C<charsets_provided>
699              
700             =item C<default_charset>
701              
702             =item C<languages_provided>
703              
704             =item C<encodings_provided>
705              
706             =item C<variances>
707              
708             =back
709              
710             However, they are only needed if the application does complex content
711             negotiation.
712              
713              
714             =head2 Part Three (resource existence)
715              
716             When we have made it past content negotiation, we know more than just which
717             routines will be used to process the request entity (if any) and generate the
718             response. We have gathered quite a bit of information about the request. All
719             this information has been pushed onto the context, so it is available to all
720             our resource methods, including the resource handler which we will get to
721             presently. This information includes:
722              
723             (FIXME: verify this list as it is outdated)
724              
725             =over
726              
727             =item C<method>
728              
729             The request method
730              
731             =item C<resource_name>
732              
733             The resource name, which can be used as a key to look up the full resource
734             definition in the C<< $Web::MREST::InitRouter::resources >>
735              
736             =item C<handler_name>
737              
738             The name of the resource handler, e.g. C<handler_bugreport>. In L<Web::MREST>,
739             the resource handlers reside in the L<Web::MREST::Dispatch> module.
740              
741             =item C<uri>
742              
743             The full URI provided with the request
744              
745             =item C<uri_base>
746              
747             The base part of the URI (e.g. "http://localhost:5000/" )
748              
749             =item C<uri_path>
750              
751             The relative path to the resource (e.g. "/bugreport")
752              
753             =item C<components>
754              
755             Reference to an array the elements of which are the individual 'components'
756             (i.e., everything between the '/' characters) of the C<uri_path>
757              
758             =item C<mapping>
759              
760             A hashref mapping resource parameter names (if any) to their values
761              
762             =item C<content-length>
763              
764             The content-length header.
765              
766             =item C<content-type>
767              
768             The content-type header.
769              
770             =back
771              
772             One major piece of information is missing, however: whether the resource exists
773             or not. For that, we have to actually call the resource handler.
774              
775              
776             =head3 C<resource_exists> (G7)
777              
778             The term "resource" is not precisely defined. It can refer to the resource
779             definition (a data structure), the resource handler (a Perl subroutine called
780             as an object method), or an object (set of records) in an underlying database.
781             Or it can refer to all of the above, or to something else. The following
782             paragraphs describe L<Web::MREST>'s approach.
783              
784             By the time control reaches this method, the request URI has already been
785             matched to a resource definition. So the resource handler is known. Since we
786             have no other way of knowing, we ask the resource itself, by calling the
787             handler with the scalar value C<1> (i.e. the numeral 1) as the sole argument.
788             This handler call is referred to as the "first pass".
789              
790             How the handler is implemented does not concern us. We only ask that it return
791             a boolean value (true or false) when called with this argument. If the return
792             value from the handler is true, we can assume that the handler will be called
793             again (second pass) in the response generation phase - read on.
794              
795              
796             =head2 Part Four (generation of response entity)
797              
798             At this point we have
799              
800             =over
801              
802             =item gathered information about the request and placed it on the context
803              
804             =item run the resource handler (first pass) to determine resource existence
805              
806             =back
807              
808             Up until now (i.e., through determination of resource existence), the FSM
809             has been a series of steps applied, in the same order, regardless of the
810             HTTP method.
811              
812             In the sections below, we examine how responses are generated for each of
813             four HTTP methods (C<GET>, C<PUT>, C<POST>, and C<DELETE>) when the resource
814             exists and when it doesn't exist.
815              
816             =head3 Resource exists
817              
818             =head4 C<GET>
819              
820             =over
821              
822             =item 1. C<content_types_provided> method call
823              
824             First, C<content_types_provided> is called to determine the name of the
825             method that is capable of generating the response in the required format.
826             This method is the one we mean when we refer to the "response generator".
827              
828             =item 2. Response generator method call
829              
830             Second, the response generator is called (from C<o18> in
831             L<Web::Machine::FSM::States>). It is expected to always return an
832             L<App::CELL::Status> object. If an error condition is detected, the
833             handler should declare it using C<< $self->mrest_declare_status >>
834             and then return a "non_ok" status.
835              
836             =back
837              
838             C<GET> is the only request method that demands a response entity
839             in the format specified by the C<Accept> header. For the other methods,
840             response entities are optional, but recommended. In practice, this
841             means that we have to create them ourselves.
842              
843              
844             =head4 C<POST>
845              
846             Here we have two possible paths, depending on the value returned by
847             C<post_is_create>:
848              
849             =over
850              
851             =item C<post_is_create> true
852              
853             =over
854              
855             =item C<create_path> and C<create_path_after_handler>
856              
857             If, and only if, C<post_is_create> is true, processing continues via
858             C<create_path> and C<create_path_after_handler>. Depending on the value of the
859             latter, the request handler (determined by consulting
860             C<content_types_accepted>) is called either before or after C<create_path>.
861              
862             The request handler should stage the response entity in preparation for
863             finalization. The content type can be inferred from
864             C<< $request->env->{'web.machine.context'} >>.
865              
866             =item Finalization
867              
868             Request is finalized by a call to C<finish_request>.
869              
870             =back
871              
872             =item C<post_is_create> false
873              
874             If C<post_is_create> returns false, all bets are off. For reasons I do not
875             understand, L<Web::Machine> does not consult C<content_types_provided> or
876             C<content_types_accepted> on this type of request. The only thing it does is
877             call C<process_post>, and so it is up to this method to do whatever needs to be
878             done to generate an entity and get it into the response.
879              
880             L<Web::MREST> helps by making sure that the content type is stored in the
881             context (in the C<'content_type'> property), so C<process_post> can look
882             there for it and generate the response entity accordingly.
883              
884             =back
885              
886              
887             =head4 C<PUT>
888              
889             On all C<PUT> requests, and those C<POST> requests that are handled as
890             C<PUT> requests (see above), L<Web::Machine> uses the following process:
891              
892             =over
893              
894             =item C<content_types_accepted>
895              
896             This method is called to determine the name of the method that can process
897             the request body. This method is expected not only to process the request
898             body, but also to generate the response. Therefore, we refer to this
899             method as the "response generator" for C<PUT> requests.
900              
901             =item Response generator method call
902              
903             Next, the response generator is called. For C<PUT> requests, the response
904             generator is determined from C<content_types_accepted> based on the Here again, the method referred
905             to by C<content_types_provided> is not called by L<Web::Machine>, but the
906             response generator is free to call C<content_types_provided> and find
907             out the method itself, and call it. Or do something else.
908              
909             When C<resource_exists> is true, the response generator is called from C<o14>
910             in L<Web::Machine::FSM::States>.
911              
912             =back
913              
914             Whenever a new resource is created, a C<Location> header is added to
915             the response with the URI path of the new resource.
916              
917             In general, we understand C<PUT> to be a request to write to a resource.
918             Typically, this will involve either creating (INSERT) or modifying (UPDATE) one
919             or more database records/objects.
920              
921             Therefore, it has to be possible for a URI to resolve to a resource that
922             does not yet exist. For example:
923              
924             PUT employee/nick/Bubba
925              
926             There may or may not be an employee by the name of Bubba in the database,
927             but if we have a resource called 'employee/nick/:nick', Path::Router will
928             match it in C<allowed_methods> and the resource handler will be called in
929             C<resource_exists> - up until this point, the same sequence of method
930             calls is used for C<GET>, C<POST>, C<PUT>, and C<DELETE>.
931              
932             L<Web::MREST> has no way of knowing whether there is an employee named Bubba.
933             It is up to the handler to determine this, and then do an INSERT or UPDATE
934             operation as appropriate. This operation is not expected to fail, but if it
935             does fail the handler should force a 4xx or 5xx status code (and provide an
936             explanation) by calling C<< $self->mrest_declare_status >>.
937              
938             If the request causes a new object - and, hence, a new resource - to be
939             created, the handler should cause a C<Location> header with the URI of the
940             new resource to be added to the response. This tells L<Web::Machine> to
941             set the response status to C<201 Created>.
942              
943             If the request only modifies an existing object/resource, simply do not
944             add a C<Location> header to the response. This will cause L<Web::Machine>
945             to return a C<200 OK> status in the response.
946              
947              
948             =head4 C<DELETE>
949              
950             For C<DELETE>, two methods are called: C<delete_resource> and
951             C<delete_completed>. The C<delete_resource> method should enact the delete
952             operation and generate the response entity. The second method, C<delete_completed>,
953             is for cases when the delete operation cannot be guaranteed to have completed -
954             this method defaults to false, but if it returns true L<Web::Machine> will
955             trigger a C<...> response.
956              
957              
958             =head3 Resource does not exist
959              
960             =head4 C<GET>
961              
962             Request goes to finalization with 404 status.
963              
964             =head4 C<POST>
965              
966             Request goes to C<allow_missing_post>, which always returns false in
967             L<Web::MREST>'s implementation.
968              
969             After that, the request goes to finalization with 404 status.
970              
971             If the
972              
973             =head4 C<PUT>
974              
975              
976              
977             =head2 C<finish_request>
978              
979             The previous sections should suffice for the reader to gain a degree of
980             understanding of how the state machine works for various types of requests, and
981             how L<Web::MREST> interfaces with the response handlers.
982              
983             The last cog of the FSM is C<finish_request>.
984              
985              
986              
987             =head1 IN-DEPTH DISCUSSIONS OF VARIOUS TOPICS
988              
989             =head2 Resource definitions
990              
991             As we read in the "crash course" above, resources are central to what a REST
992             server is and does: the server processes incoming requests. Each request has
993             a URI which resolves (or does not resolve) to a resource. Resources are
994             defined as module variables: each module that contains resource handlers
995             should also define a module variable (via C<our $resource_defs = { ... };>)
996             containing the definitions of the resources covered by that module.
997              
998             The top-level dispatch module, L<Web::MREST::Dispatch>, should implement
999             a method called C<init_router> which calls the function
1000              
1001             Web::MREST::InitRouter::load_resource_defs
1002              
1003             for all the resource-defining modules. When the first HTTP request comes in,
1004             L<Web::MREST::Resource> calls the C<init_router> method. This only happens
1005             once, ensuring that the resource definitions are fully loaded for the first -
1006             and all subsequent - requests.
1007              
1008             Each resource definition is a hashref consisting of a number of properties.
1009             This definition hashref is itself included in the C<$resources> package
1010             hashref, which essentially looks like this:
1011              
1012             {
1013             RESOURCE_NAME => RESOURCE_DEFINTION,
1014             RESOURCE_NAME => RESOURCE_DEFINTION,
1015             RESOURCE_NAME => RESOURCE_DEFINTION,
1016             }
1017              
1018             where C<RESOURCE_NAME> is a resource name (a string like C<'/'> or
1019             C<'docu/text'>) and C<RESOURCE_DEFINITION> is that resource's definition
1020             hashref.
1021              
1022             The root resource should be defined under the name C<'/'> and top-level
1023             resources should have a C<parent> property set to this string.
1024              
1025             In the resource definition, properties can be specified either as a
1026             scalar value, in which case the definition applies to all the methods
1027             specified in C<< $site->MREST_SUPPORTED_HTTP_METHODS >>, or as a
1028             hashref in case the given resource is only defined for certain methods.
1029              
1030             In the latter case, it is not necessary to define all properties as
1031             hashrefs. The set of permitted methods will always be taken from the
1032             'handler' property. For example in this snippet whizzo_resource is only
1033             defined for the GET method, and that will be applied to 'foo' (and the
1034             rest of this resource's properties) as well.
1035              
1036             'whizzo_resource' => {
1037             'handler' => {
1038             'GET' => 'some_method',
1039             },
1040             'foo' => 'barbazbat',
1041             ...
1042             }
1043              
1044             So 'foo' will only be defined for the GET method.
1045              
1046             Examples:
1047              
1048             'foo_prop' => 'value applied to all available methods',
1049              
1050             'bar_prop' => {
1051             'GET' => 'value applied to GET requests',
1052             'POST' => 'value applied to POST requests',
1053             },
1054              
1055             There is one required property, 'handler', which is used to specify the
1056             handler(s) for the resource (see the examples below). The value of this
1057             property is taken to be the name of a method. This method call looks
1058             like this:
1059              
1060             $self->$handler
1061              
1062             and is located in Web::MREST::Resource->resource_exists
1063              
1064             (The inheritance chain is set up in C<bin/mrest> - the server startup script -
1065             and via C<use parent> statements in the various modules that make up the
1066             inheritance chain.)
1067              
1068             In addition, each resource may have any properties you, the application
1069             developer, wish to invest in it. For our 'docu' methods we use the
1070             properties 'description' and 'documentation', for example.
1071              
1072             Two properties - 'parent' and 'validations' - are
1073             exceptions to the above and should never be defined on a per-method
1074             basis:
1075              
1076             - 'validations' contains validation checks to be applied when matching
1077             URI to resource (for more information, see the Path::Router
1078             documentation).
1079            
1080             - 'parent' contains the name of the resource's parent resource
1081             (defaults to '' - the root resource)
1082              
1083             - 'documentation' is reserved for the self-documentation feature
1084              
1085              
1086              
1087             =head3 C<Path::Router> object initialization
1088              
1089             When the server starts, the C<MREST_RESOURCE_DEFINITIONS> and
1090             C<MREST_ROOT_RESOURCE> meta parameters are initialized from the configuration
1091             file C<config/dispatch_MetaConfig.pm> in the L<Web::MREST> distribution.
1092              
1093             The application developer will of course want to define her own set of
1094             resources. This should be done by manipulating the meta parameters
1095             C<MREST_RESOURCE_DEFINITIONS> and C<MREST_ROOT_RESOURCE>. A good place
1096             to do this is in the application's C<mrest_init_router> routine.
1097              
1098             Here are two approaches to defining the application's resources, depending on
1099             whether the application wishes to retain the L<Web::MREST> resources.
1100              
1101             =over
1102              
1103             =item 1. retain
1104              
1105             package MyApp::Resource;
1106              
1107             use Clone 'clone';
1108             use parent 'Web::MREST::Resource';
1109              
1110             # We assume that the application somehow loads its resource definitions
1111             # (including the root resource) into a package variable $r_defs -- for
1112             # example by hard-coding them like this
1113             my $r_defs = { ... };
1114              
1115             # ----------------------------------------
1116             # mrest_init_router - called by Web::MREST
1117             # ----------------------------------------
1118             sub mrest_init_router {
1119             my $self = shift;
1120              
1121             # set up the root resource
1122             $meta->set( 'MREST_ROOT_RESOURCE', $r_defs->{''} );
1123             delete $r_defs->{''};
1124              
1125             # set up the remaining resources, retaining (but possibly
1126             # overwriting) the Web::MREST default resources
1127             my $mrest_defs = clone( $meta->MREST_RESOURCE_DEFINITIONS );
1128             foreach my $r_name ( keys %$r_defs ) {
1129             $mrest_defs->{$r_name} = $r_defs->{$r_name};
1130             }
1131             $meta->set( 'MREST_RESOURCE_DEFINITIONS', $mrest_defs );
1132             }
1133              
1134             =item 2. do not retain
1135              
1136             This approach is more simple because no C<mrest_init_router> need be written.
1137             The application should have its own distro sharedir C<config/> and therein a
1138             file C<dispatch_MetaConfig.pm>. Inside that file, the application puts its own
1139             resource definitions in the C<MREST_RESOURCE_DEFINITIONS> and
1140             C<MREST_ROOT_RESOURCE> parameters (refer to C<config/dispatch_MetaConfig.pm> in
1141             the L<Web::MREST> distribution for syntax and semantics).
1142              
1143             The application's definitions will overlay (i.e. replace) those of
1144             L<Web::MREST>. Even in this scenario, some or all of L<Web::MREST>'s resources
1145             could be used in the application, but only by copy-pasting the definitions and
1146             their respective handlers into the application's source code.
1147              
1148             =back
1149              
1150              
1151             =head3 Tree structure
1152              
1153             L<Web::MFILE> allows resources to be defined in a tree structure. It is
1154             designed to allow a tree structure to be described in a flat configuration
1155             file. The C<MREST_RESOURCE_DEFINITIONS> hash is keyed on the resource name.
1156             Child resources are indicated by including a C<parent> property with the name
1157             of the parent resource. Care should be exercised not to introduce any circular
1158             references.
1159              
1160             If a flat structure is desired, simply do not include any C<parent> properties
1161             in your resource definitions.
1162              
1163             The format of C<MREST_RESOURCE_DEFINITIONS> hash is documented in
1164             C<config/dispatch_MetaConfig.pm>.
1165              
1166              
1167             =head3 C<< $Web::MREST::InitRouter::resources >>
1168              
1169             The resource definition hashrefs in the dispatch modules are designed to be
1170             written and maintained by humans. When the C<init_router> method runs, it loops
1171             over all the resource definitions and builds up a second hash,
1172             C<< $Web::MREST::InitRouter::resources >>, which contains the same information
1173             in a format that is more convenient for automated processing.
1174              
1175             Since the resource definitions are a potential source of typographical and
1176             semantic errors, you should dump this package variable to the log and examine
1177             it to make sure your resource definitions are being processed correctly.
1178              
1179              
1180             =head2 Errors
1181              
1182             As we move through the state machine (i.e. the chain of method calls driven
1183             by L<Web::Machine>), we build up a "context" from which we generate the HTTP
1184             response. Stated very simply, the response code can either be 'OK' (200) or
1185             "something else" - i.e., an error of some kind.
1186              
1187             And, indeed, checking for errors accounts for a large portion of what our
1188             resource modules do. As RFC2616 explains, errors can be divided into two
1189             brought classes: client errors and server errors.
1190              
1191             =over
1192              
1193             =item Client errors (4xx)
1194              
1195             Client errors have status codes that start with 4 (e.g. 400, 401, 404).
1196              
1197             RFC2616 has this to say about them:
1198              
1199             The 4xx class of status code is intended for cases in which the client
1200             seems to have erred. Except when responding to a HEAD request, the server
1201             SHOULD include an entity containing an explanation of the error situation, and
1202             whether it is a temporary or permanent condition. These status codes are
1203             applicable to any request method. User agents SHOULD display any included
1204             entity to the user.
1205              
1206             =item Server errors (5xx)
1207              
1208             Server errors have codes beginning with th digit "5". According to RFC2616,
1209             they
1210              
1211             indicate cases in which the server is aware that it has erred or is
1212             incapable of performing the request. Except when responding to a HEAD
1213             request, the server SHOULD include an entity containing an explanation of
1214             the error situation, and whether it is a temporary or permanent condition.
1215             User agents SHOULD display any included entity to the user. These response
1216             codes are applicable to any request method.
1217              
1218             =back
1219              
1220             The key point here is that it is not sufficient to return a bare 4xx or 5xx
1221             response status code. The response should include an entity body with an
1222             explanation of the error condition.
1223              
1224             =head3 How to provide explanation in response entity
1225              
1226             L<Web::MREST> provides a mechanism for adding the explanation to the entity
1227             body as called for by RFC2616. At the exact place in your resource module
1228             where you discover the error, do something like this:
1229              
1230             $self->mrest_declare_status( code => '400', explanation => 'You messed up' );
1231              
1232             This will be converted into the respective L<App::CELL::Status> object and
1233             returned in the response entity. The object will have properties like this:
1234              
1235             {
1236             level => 'ERR',
1237             code => 'You messed up',
1238             payload => {
1239             http_code => '500',
1240             uri_path => ... (taken from the context),
1241             resource_name => ... (taken from the context),
1242             found_in => ... (taken from 'caller'),
1243             permanent => JSON::true (the default),
1244             },
1245             }
1246              
1247             Alternatively, you can pass in your own arbitary L<App::CELL::Status> object.
1248              
1249             To see how the L<App::CELL::Status> object becomes the response entity, see
1250             the C<finish_request> method in L<Web::MREST::Resource>.
1251              
1252              
1253             =head2 Context
1254              
1255             Typically referred to as C<$context>, the "MREST context" is a hashref that is
1256             built up during the course of request processing. In addition to being used
1257             within L<Web::MREST::Resource>, it is always sent as an argument whenever
1258             L<Web::MREST::Resource> calls a hook, so the developer can modify it in her
1259             implementations of the various hook routines.
1260              
1261              
1262             =head2 Authentication
1263              
1264             Ever since the Big Bad Wolf ate Granny, authentication mechanisms have been
1265             prone to abuse by individuals who are willing to lie about their identity.
1266              
1267             Humans are good at distinguishing one human from another, provided they can
1268             apply all their senses to the task. Computers lack proper senses and are
1269             downright awful at this task. Computerized authentication schemes typically
1270             operate by presenting the user with one or more hoops to jump through. Whoever
1271             succeeds at this task is deemed to be the user. What could go wrong?
1272              
1273             Passwords (or passphrases) are the "hoop" most frequently used to authenticate
1274             users and keep would-be intruders out. Therefore, a system's security is often
1275             gauged by how well it protects user credentials from disclosure. Since
1276             usernames are public, the only thing keeping a determined intruder at bay are
1277             the passwords, and various measures are taken to protect them.
1278              
1279             From the perspective of L<Web::Machine>, authentication is a matter of
1280             calling the L<is_authorized> method. If the return value is false, the response
1281             will be C<401 Unauthorized>. If it is true, request processing continues.
1282             Whatever authentication measures the application developer decides to implement
1283             should be triggered by this method call.
1284              
1285             For more about L<is_authorized>, see the L<Web::Machine::Resource documentation|https://metacpan.org/pod/Web::Machine::Resource#is_authorized-authorization_header>
1286              
1287              
1288              
1289             =head2 Authorization
1290              
1291             Once authentication has determined the user's identity, a related task,
1292             authorization, begins. As the name would imply (and the RFC's vague
1293             use of the term "authorization" notwithstanding), authorization answers
1294             the question:
1295              
1296             Is this specific user authorized to make this request?
1297              
1298             Compare this with authentication, which answers a different question:
1299              
1300             Is this user really who they are purporting to be?
1301              
1302             Or, even more pithily:
1303              
1304             Who is this user?
1305              
1306             Authorization implies a boolean "function" (in both the mathematical and
1307             computer science sense) that takes three arguments: the username, the HTTP
1308             method, and the resource. Implementation of this function is left to the
1309             application developer.
1310              
1311             It is worth noting here that L<Web::Machine> provides a C<forbidden> method.
1312             Since C<is_authorized> is already taken for authentication, we can use
1313             C<forbidden> for authorization. Just be sure to understand thoroughly that
1314             a true return value from C<forbidden> means "not authorized".
1315              
1316              
1317             =head2 Customized URI parsing
1318              
1319             While L<Web::MREST> provides for URI parsing using L<Path::Router>, if this is
1320             not desired the application developer can parse URIs herself by simply
1321             substituting her own C<init_router> and C<match> methods for the ones provided
1322             by L<Path::Router> and L<Path::Router::Route::Match>, respectively.
1323              
1324             When request processing enters C<resource_exists>,
1325             Alternatively, the application developer can overlay the C<init_router> routine
1326             with one that returns an arbitrary object (stored in C<$router>) that has a
1327             C<match> method. After that, L<Web::MREST> does
1328              
1329             my $match = $router->match( $path );
1330              
1331             where C<$path> is the relative portion of the URI (i.e. everything left after
1332             the C<http://myapp.example.com/> part is cut off).
1333              
1334             The C<$match> object should provide a C<route> method, which should return the
1335             definition of the matched resource. See L<"RESOURCE DEFINITIONS">.
1336              
1337              
1338             =head1 FUNCTIONS IN THIS MODULE
1339              
1340             =head2 init
1341              
1342             Do initialization-like things, such as loading configuration parameters.
1343             Takes a PARAMHASH which can contain one of the following:
1344              
1345             =over
1346              
1347             =item C<distro>
1348              
1349             The name of the application distribution from which the distro sharedir will be
1350             loaded.
1351              
1352             =item C<path>
1353              
1354             The name (full path) of a directory containing the application's configuration
1355             files.
1356              
1357             =item C<hashref>
1358              
1359             A reference to a hash containing meta parameters to be loaded.
1360              
1361             =back
1362              
1363             =cut
1364              
1365             sub init {
1366 22     22 1 1186 my %ARGS = validate( @_, {
1367             distro => { type => SCALAR, optional => 1 },
1368             sitedir => { type => SCALAR, optional => 1 },
1369             hashref => { type => HASHREF, optional => 1 },
1370             early_debug => { type => SCALAR, optional => 1 },
1371             } );
1372            
1373 22         136 my $tf = $ARGS{'early_debug'};
1374 22 50       95 if ( $tf ) {
1375 0         0 _touch $tf;
1376 0 0 0     0 if ( -r $tf and -w $tf ) {
1377 0         0 unlink $tf;
1378 0         0 Log::Any::Adapter->set( 'File', $tf );
1379 0         0 $log->debug( __PACKAGE__ . "::init activating early debug logging to $tf" );
1380             } else {
1381 0         0 print "Given unreadable/unwritable early debugging filespec $tf\n";
1382             }
1383             }
1384              
1385             # always load Web::MREST's configuration parameters
1386 22         132 my $target = File::ShareDir::dist_dir('Web-MREST');
1387 22         2182 $log->debug( "About to load Web::MREST configuration parameters from $target" );
1388 22         4079 my $status = $CELL->load( sitedir => $target, verbose => 1 );
1389 22 50       92639 return $status if $status->not_ok;
1390              
1391 22         438 $meta->set( 'MREST_EARLY_DEBUGGING', $tf );
1392              
1393             # if argument provided, load that, too
1394 22 50       1581 if ( %ARGS ) {
1395 0         0 $target = undef;
1396 0 0 0     0 if ( $ARGS{'distro'} and $ARGS{'distro'} ne 'Web-MREST' ) {
1397             # distro must be given as "MyApp-Foo", not "MyApp::Foo"
1398 0         0 $target = File::ShareDir::dist_dir( $ARGS{'distro'} );
1399 0         0 $status = $CELL->load( sitedir => $target );
1400 0 0       0 return $status if $status->not_ok;
1401             }
1402 0 0       0 if ( my $sitedir_target = $ARGS{'sitedir'} ) {
1403 0 0       0 if ( -d $sitedir_target ) {
1404 0         0 $status = $CELL->load( sitedir => $sitedir_target );
1405 0 0       0 return $status if $status->not_ok;
1406             } else {
1407 0         0 $log->warn( 'Web::MREST::init() says sitedir argument given, but it is not a directory: ' .
1408             Dumper( $sitedir_target ) );
1409             }
1410             }
1411 0 0       0 if ( $ARGS{'hashref'} ) {
1412 0         0 my $count = 0;
1413 0         0 foreach my $key ( keys %{ $ARGS{'hashref'} } ) {
  0         0  
1414 0         0 $meta->set( $key, $ARGS{'hashref'}->{$key} );
1415 0         0 $count += 1;
1416             }
1417 0         0 $log->notice( "Web::MREST::init loaded $count meta parameters from a hashref" );
1418             }
1419             }
1420              
1421 22         135 return $CELL->status_ok;
1422             }
1423              
1424              
1425             =head2 version
1426              
1427             Accessor method (to be called like a constructor) providing access to C<$VERSION> variable
1428              
1429             =cut
1430              
1431 2     2 1 594 sub version { $VERSION; }
1432              
1433             1;