File Coverage

blib/lib/WebAPI/DBIC.pm
Criterion Covered Total %
statement 6 6 100.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 8 8 100.0


line stmt bran cond sub pod time code
1             package WebAPI::DBIC;
2             $WebAPI::DBIC::VERSION = '0.003002';
3 2     2   1280684 use strict; # keep our kwalitee up!
  2         25  
  2         163  
4 2     2   34 use warnings;
  2         5  
  2         186  
5             1;
6              
7             __END__
8              
9             =pod
10              
11             =encoding UTF-8
12              
13             =head1 NAME
14              
15             WebAPI::DBIC
16              
17             =head1 VERSION
18              
19             version 0.003002
20              
21             =head1 DESCRIPTION
22              
23             WebAPI::DBIC provides the parts you need to build a feature-rich RESTful JSON web
24             service API backed by DBIx::Class schemas.
25              
26             WebAPI::DBIC features include:
27              
28             * Built on the strong foundations of L<Plack> and L<Web::Machine>, plus
29             L<Path::Router> as the router. (Other routers could be supported.)
30              
31             * Built as fine-grained roles for maximum reusability and extensibility.
32              
33             * Integrates with other L<Plack> based applications.
34              
35             * The resource roles can be added to your existing application.
36              
37             * Rich support for multiple hypermedia types, including JSON API
38             (application/vnd.api+json) and HAL (application/hal+json).
39             The Collection+JSON and JSON-LD hypermedia types could be added in future.
40              
41             * Automatic detection and exposure of result set relationships.
42              
43             * Supports safe robust multi-related-record CRUD transactions.
44              
45             * An example .psgi file that gives you an instant web service for any
46             DBIx::Class schema.
47              
48             * Includes a generic HAL API browser application so you can be browsing your
49             new API in minutes.
50              
51             =head2 HAL - Hypertext Application Language
52              
53             The Hypertext Application Language hypermedia type (or HAL for short)
54             is a simple JSON format that gives a consistent and easy way to hyperlink
55             between resources in your API.
56              
57             Adopting HAL makes the API explorable, and its documentation easily
58             discoverable from within the API itself. In short, it will make your API
59             easier to work with and therefore more attractive to client developers.
60              
61             A JavaScript "HAL Browser" is included in the WebAPI::DBIC distribution.
62             (WebAPI::DBIC doesn't yet offer direct support for documentation resources.)
63              
64             APIs that adopt HAL can be easily served and consumed using open source
65             libraries available for most major programming languages. It's also simple
66             enough that you can just deal with it as you would any other JSON.
67              
68             See L<http://stateless.co/hal_specification.html> for more details.
69              
70             =head2 JSON API
71              
72             The JSON API media type is designed to minimize both the number of requests and
73             the amount of data transmitted between clients and servers. This efficiency is
74             achieved without compromising readability, flexibility, and discoverability.
75              
76             See L<http://jsonapi.org/> for more details.
77              
78             For Ember, L<https://github.com/kurko/ember-json-api> can be used as an adaptor.
79              
80             STATUS:
81              
82             Support for JSON API within WebAPI::DBIC is maturing rapidly.
83              
84             Fetching compound documents, including "links" data (relationship templates)
85             and "linked" (side-loaded/prefetch) resources, is supported.
86             The sort= parameter is supported, in it's simple form.
87              
88             Main TO-DOs in approximate order of likely implementation:
89              
90             - settle on how "type" is defined (currently it's derived from the router)
91             - provide "links" separately to prefetch logic
92             - support collection urls, e.g. /photos/1,2,3
93             - support relationship urls, e.g. /photos/1/links/photographer
94             - support include= in addition to prefetch=
95             - support multiple sorts, e.g. sort[posts]=-created,title&sort[people]=name
96             - support the "name[type]" style of field= param value
97             - support creating resources via the application/vnd.api+json media type
98             - support updating resources via the application/vnd.api+json media type
99             - support updating relationships via the application/vnd.api+json media type
100             - support the suggest error format
101             - support PATCH requests
102              
103             =head2 Web::Machine
104              
105             The L<Web::Machine> module provides a RESTful web framework modeled as a formal
106             state machine. This is a rigorous and powerful approach, originally developed
107             in Erlang and since ported to many other languages.
108              
109             See L<https://raw.githubusercontent.com/basho/webmachine/develop/docs/http-headers-status-v3.png>
110             for an image of the state machine.
111              
112             By building on Web::Machine, WebAPI::DBIC removes the need to implement all the
113             logic needed for accurate and full-featured HTTP protocol behaviour.
114             You just provide small pieces of logic at the decision points you care about
115             and Web::Machine looks after the rest.
116              
117             See L<https://github.com/basho/webmachine/wiki> for more information.
118              
119             Web::Machine provides the logic to handle a HTTP request for a I<single resource>.
120              
121             With WebAPI::DBIC those resources typically represent a DBIx::Class result set,
122             a row, or a method invocation on a row. They are implemented as a subclass of
123             L<Web::Machine::Resource> that consumes a some set of WebAPI::DBIC roles which add
124             the desired functionality to the resource.
125              
126             =head2 Path::Router
127              
128             The L<Path::Router> module is used to organize multiple resources into a URL
129             namespace. It's used to route incoming requests to the appropriate Web::Machine
130             instance. It's also used in reverse to construct links to other resources that
131             are included in the outgoing responses.
132              
133             Path::Router supports full reversability: the value produced by a path match
134             can be passed back in and you will get the same path you originally put in.
135             This removes ambiguity and reduces mis-routings. This is important for
136             WebAPI::DBIC because, for each resource returned, it automatically add HAL
137             C<_links> containing the URLs of the related resources, as defined by the
138             DBIx::Class schema. This is what makes the API discoverable and browseable.
139              
140             =head1 NAME
141              
142             WebAPI::DBIC - A composable RESTful JSON API to DBIx::Class schemas using roles and Web::Machine
143              
144             =head1 STATUS
145              
146             The WebAPI::DBIC code has been in production use since early 2013, however it's
147             only recently been open sourced (July 2014) so it's still lacking in documentation.
148             It's also undergoing a period of refactoring, enhancement and evolution now
149             there are more developers contributing and the code is being applied to more domains.
150              
151             Interested? Please get involved! See L</HOW TO GET HELP> below.
152              
153             =head1 QUICK START
154              
155             To demonstrate the rich functionality that the combination of DBIx::Class and
156             HAL provides, the WebAPI::DBIC framework includes a ready-to-use L<Plack> .psgi
157             file that provides an instant web data service for any DBIx::Class schema.
158              
159             $ git clone https://github.com/timbunce/WebAPI-DBIC.git
160             $ cd WebAPI-DBIC
161             $ cpanm Module::CPANfile
162             $ cpanm --installdeps . # this may take a while
163              
164             $ export WEBAPI_DBIC_SCHEMA=DummyLoadedSchema
165             $ plackup -Ilib -It/lib webapi-dbic-any.psgi
166             ... open a web browser on port 5000 to browse the API
167              
168             Then try it out with your own schema:
169              
170             $ export WEBAPI_DBIC_SCHEMA=Foo::Bar # your own schema
171             $ export WEBAPI_DBIC_HTTP_AUTH_TYPE=none # recommended
172             $ export DBI_DSN=dbi:Driver:... # your own database
173             $ export DBI_USER=... # for initial connection, if needed
174             $ export DBI_PASS=... # for initial connection, if needed
175             $ plackup -Ilib webapi-dbic-any.psgi
176             ... open a web browser on port 5000 to browse your new API
177              
178             The API is read-only by default. To enable PUT, POST, DELETE etc, set the
179             C<WEBAPI_DBIC_WRITABLE> environment variable.
180              
181             =head1 MODULES
182              
183             =head2 Core Roles
184              
185             L<WebAPI::DBIC::Resource::Role::DBIC> is responsible for interfacing with
186             L<DBIx::Class>, 'rendering' individual records as resource data structures.
187             It also interfaces with Path::Router to handle relationship linking.
188              
189             L<WebAPI::DBIC::Resource::Role::Set> is responsible for accepting GET and HEAD
190             requests for set resources (collections) and returning the results as JSON.
191              
192             L<WebAPI::DBIC::Resource::Role::SetWritable> is responsible for accepting POST
193             request for set resources. It handles the recursive creation of related records.
194             Related records can be nested to any depth and are created from the bottom up
195             within a transaction.
196              
197             L<WebAPI::DBIC::Resource::Role::Item> is responsible for GET and HEAD requests
198             for single item resources and returning the results as JSON.
199              
200             L<WebAPI::DBIC::Resource::Role::ItemWritable> is responsible for accepting PUT
201             and DELETE requests for single item resources. It handles the recursive update of
202             related records. Related records can be nested to any depth and are updated
203             from the bottom up within a transaction. Handles both 'PUT is replace' and
204             'PUT is update' logic.
205              
206             L<WebAPI::DBIC::Resource::Role::ItemInvoke> is responsible for accepting POST
207             requests for single item resources representing the invocation of a specific
208             method on an item (e.g. POST /widget/42/invoke/my_method_name?args=...).
209              
210             L<WebAPI::DBIC::Resource::Role::DBICAuth> is responsible for checking
211             authorization to access a resource. It currently supports Basic Authentication,
212             using the DBI DSN as the realm name and the return username and password as the
213             username and password for the database connection.
214              
215             L<WebAPI::DBIC::Resource::Role::DBICParams> is responsible for handling request
216             parameters related to DBIx::Class such as C<page>, C<rows>, C<sort>, C<me>,
217             C<prefetch>, C<fields> etc.
218              
219             =head2 JSON+HAL Roles
220              
221             These roles are used to handle requests using the C<application/hal+json> media type
222             and follow the naming convention used above.
223              
224             L<WebAPI::DBIC::Resource::HAL::Role::DBIC>
225              
226             L<WebAPI::DBIC::Resource::HAL::Role::Set>
227              
228             L<WebAPI::DBIC::Resource::HAL::Role::SetWritable>
229              
230             L<WebAPI::DBIC::Resource::HAL::Role::Item>
231              
232             L<WebAPI::DBIC::Resource::HAL::Role::ItemWritable>
233              
234             =head2 JSON API Roles
235              
236             These roles are used to handle requests using the C<application/vnd.api+json> media type
237             and follow the naming convention used above.
238              
239             L<WebAPI::DBIC::Resource::JSONAPI::Role::DBIC>
240              
241             L<WebAPI::DBIC::Resource::JSONAPI::Role::Set>
242              
243             L<WebAPI::DBIC::Resource::JSONAPI::Role::SetWritable>
244              
245             L<WebAPI::DBIC::Resource::JSONAPI::Role::Item>
246              
247             L<WebAPI::DBIC::Resource::JSONAPI::Role::ItemWritable>
248              
249             =head2 Utility Roles
250              
251             L<WebAPI::DBIC::Role::JsonEncoder> provides encode_json() and decode_json() methods.
252              
253             L<WebAPI::DBIC::Role::JsonParams> provides a param() method that returns query
254             parameters, except that any parameters with names that have a C<~json> suffix
255             have their values JSON decoded, so they can be arbitrary data structures.
256              
257             =head2 Resource Classes
258              
259             To make building typical applications easier, WebAPI::DBIC provides four
260             pre-defined resource classes:
261              
262             L<WebAPI::DBIC::Resource::GenericCore> is a base class that consumes all the
263             general-purpose resource roles.
264              
265             L<WebAPI::DBIC::Resource::GenericItem> subclasses GenericCore and consumes
266             extra roles for resources represented by an individual DBIx::Class row.
267              
268             L<WebAPI::DBIC::Resource::GenericSet> subclasses GenericCore and consumes extra
269             roles for resources represented by a DBIx::Class result set.
270              
271             L<WebAPI::DBIC::Resource::GenericItemInvoke> subclasses GenericCore and
272             consumes extra roles for resources that represent a specific method call on an
273             item resource.
274              
275             These classes are I<very> simple because all the work is done by the various
276             roles they consume. For example, here's the entire code for
277             L<WebAPI::DBIC::Resource::GenericCore>:
278              
279             package WebAPI::DBIC::Resource::GenericCore;
280             use Moo;
281             extends 'WebAPI::DBIC::Resource::Base';
282             with 'WebAPI::DBIC::Role::JsonEncoder',
283             'WebAPI::DBIC::Role::JsonParams',
284             'WebAPI::DBIC::Resource::Role::Router',
285             'WebAPI::DBIC::Resource::Role::Identity',
286             'WebAPI::DBIC::Resource::Role::Relationship',
287             'WebAPI::DBIC::Resource::Role::DBIC',
288             'WebAPI::DBIC::Resource::Role::DBICException',
289             'WebAPI::DBIC::Resource::Role::DBICAuth',
290             'WebAPI::DBIC::Resource::Role::DBICParams',
291             ;
292             1;
293              
294             and L<WebAPI::DBIC::Resource::GenericItem>:
295              
296             package WebAPI::DBIC::Resource::GenericSet;
297             use Moo;
298             extends 'WebAPI::DBIC::Resource::GenericCore';
299             with 'WebAPI::DBIC::Resource::Role::Set',
300             'WebAPI::DBIC::Resource::Role::SetWritable',
301             ;
302             1;
303              
304             =head2 Other Classes
305              
306             A few other classes are provided:
307              
308             L<WebAPI::DBIC::Util.pm> provides a few general utilities.
309              
310             L<WebAPI::DBIC::WebApp> - this is the main app class and is most likely to
311             change in the near future so isn't documented much yet.
312              
313             =head1 TRANSPARENCY
314              
315             WebAPI::DBIC aims to be a fairly 'transparent' layer between your
316             L<DBIx::Class> schema and the JSON that's generated and received.
317              
318             So it's the responibility of your schema to return data in the format you want
319             in your generated URLs and JSON, and to accept data in the format that arrives
320             in requests from clients.
321              
322             For an example of how to handle dates using L<DateTime> nicely, see:
323              
324             https://blog.afoolishmanifesto.com/posts/solution-on-how-to-serialize-dates-nicely/
325              
326             =head1 COMPARISONS
327              
328             This section provides links to similar modules with a few notes about how they
329             differ from WebAPI::DBIC.
330              
331             =head2 ... others? ...
332              
333             =head2 App::AutoCRUD
334              
335             L<App::AutoCRUD> provides an automatically generated I<HTML> interface to a
336             database, including search forms. It can export data in various formats
337             including JSON but isn't designed as a JSON API, so it's not directly
338             comparable to WebAPI::DBIC. See also L<RapidApp>.
339              
340             App::AutoCRUD doesn't use DBIx::Class, it uses DBIx::DataModel (a UML-based ORM
341             framework), but creates the model on the fly. That doesn't let you build
342             business logic into the schema model the way you can with DBIx::Class.
343              
344             =head2 RapidApp
345              
346             To quote the documentation: L<RapidApp> is an extension to L<Catalyst> - the
347             Perl MVC framework. It provides a feature-rich extended development stack, as
348             well as easy access to common out-of-the-box application paradigms, such as
349             powerful CRUD-based front-ends for DBIx::Class models, user access and
350             authorization, RESTful URL navigation schemes, pure Ajax interfaces with no
351             browser page loads, templating engine with front-side CMS features, declarative
352             configuration layers, and more.
353              
354             It's not designed as a JSON API and doesn't use HAL, so it's not directly
355             comparable to WebAPI::DBIC.
356              
357             =head1 INTEGRATIONS
358              
359             This section provides information on how to integrate WebAPI::DBIC with
360             existing applications.
361              
362             =head2 Catalyst
363              
364             As with any PSGI application, WebAPI::DBIC can integrate into Catalyst fairly
365             simply with L<Catalyst::Action::FromPSGI>. Here's an example integration:
366              
367             package MyApp::Controller::HelloName;
368              
369             use base 'Catalyst::Controller';
370              
371             sub api : Path('/api') ActionClass('FromPSGI') {
372             my ($self, $c) = @_;
373              
374             WebAPI::DBIC::WebApp->new({
375             schema => $c->model('DB')->schema,
376             ...
377             })->to_psgi_app
378             }
379              
380             =head2 Dancer
381              
382             I<I'd welcome any information you could contribute here.>
383              
384             =head2 Mojolicious
385              
386             I<I'd welcome any information you could contribute here.>
387              
388             =head2 ...
389              
390             =head1 HOW TO GET HELP
391              
392             =over
393              
394             =item * IRC: irc.perl.org#webapi
395              
396             =for html <a href="https://chat.mibbit.com/#webapi@irc.perl.org">(click for instant chatroom login)</a>
397              
398             =for comment =item * RT Bug Tracker: L<https://rt.cpan.org/NoAuth/Bugs.html?Dist=WebAPI-DBIC>
399              
400             =item * Source: L<https://github.com/timbunce/WebAPI-DBIC>
401              
402             =back
403              
404             See also https://metacpan.org/pod/distribution/WebAPI-DBIC/NOTES.pod
405             and https://github.com/timbunce/WebAPI-DBIC/issues
406              
407             If there's anything you specifically need, just ask!
408              
409             =head1 CREDITS
410              
411             Stevan Little gets top billing for creating L<Web::Machine> and L<Path::Router>
412             (not to mention L<Moose> and much else besides).
413              
414             Matt Trout and Peter Rabbitson and the rest of the L<DBIx::Class> team for
415             creating and maintaining such an excellent object <-> relational mapper.
416              
417             Arthur Axel "fREW" Schmidt, both for his original "drinkup" prototype using
418             Web::Machine that WebAPI::DBIC is based on, and for offering to help with the
419             work required to open source and release WebAPI::DBIC to CPAN. Without that,
420             and further help from Fitz Elliott, WebAPI::DBIC might still be a closed source
421             internal project.
422              
423             =head1 OVERVIEW OF REPRESENTIONS AND ACTIONS
424              
425             The docs below are from old internal documentation. They're a bit rought and
426             will be reworked and found a better home. They're here for now because they are
427             useful to give a sense of how the API works and what it supports.
428              
429             =head2 GENERIC ENTITY REPRESENTIONS
430              
431             Here we define the default behavior for GET, PUT, DELETE and POST methods on
432             item and set resources.
433              
434             In these examples the ~ symbol is used to represent a common prefix. The
435             prefix is intended to contain at least a single path name element plus a
436             version number element, for example, in:
437              
438             GET ~/ecosystems/
439              
440             the ~ represents a prefix such as "/clients/v1", so the above is a shorthand
441             way of representing:
442              
443             GET /clients/v1/ecosystems/
444              
445             =head3 Conventions
446              
447             Resource names are typically plural nouns, and lower case, with underscores if required.
448             Verbs could be used for for non-resource requests and might be capitalized (e.g. /Convert?from=Y&to=Y).
449              
450             A parameter that's part of the url is represented in these examples with the
451             :name convention, e.g. :id.
452              
453             XXX That might change to the 'URL Template' RFC6570 style
454             http://tools.ietf.org/html/rfc6570
455              
456             =head2 GET Item
457              
458             GET ~/resources/:id
459              
460             returns
461              
462             {
463             _links: { ... } # optional
464             _embedded: { ... } # optional
465             _meta: { ... } # optional
466             ... # data attributes, optional
467             }
468              
469             The optional _links object holds relevant links in the HAL format
470             (see below). This enables interactive browsing of the API.
471              
472             The optional _embedded object holds embedded resources in the HAL format.
473             (see L</prefetch>).
474              
475             The optional _meta attribute might include things like the name of the
476             attribute to treat as the label, or a count of items matching a search.
477              
478             GET ~/ecosystems/1
479              
480             would include
481              
482             {
483             id: 1,
484             ...
485             person_id: 2, # foreign key
486             ...
487             _links {
488             self: {
489             href: "/ecosystems/1"
490             },
491             "relation:person": {
492             href: /person/19
493             },
494             "relation:email_domain": {
495             href: "/email_domain/8"
496             }
497             },
498             }
499              
500             The "relation" links describe the relationships this resource has with other resources.
501              
502             Also see L</prefetch>.
503              
504             =head2 GET Item - Optional Parameters
505              
506             =head3 prefetch
507              
508             Prefetch is a mechanism in DBIx::Class by which related resultsets can be returned
509             along with the primary resultset. This prefetching is performed by a single query and
510             so improves efficiency by reducing the number of database requests.
511              
512             In WebAPI::DBIC the C<prefetch> parameter enables use of DBIx::Class prefetch and
513             so allows any data in related resultsets to be returned as part of the same
514             response. This allows the user to make one GET to return most, and possibly all,
515             of the data needed by the requesting application. This reduces the number of HTTP requests.
516              
517             Note that prefetch is only effective for response types that support embedded
518             data, e.g, C<application/hal+json>.
519              
520             Prefetching in WebAPI::DBIC and DBIx::Class uses the accessor names defined in the
521             Result class for the given Resultset. These should be used in the prefetch parameter.
522              
523             The following examples assume a Schema setup similar to the following:
524              
525             package MyApp::Schema::Result::Artist;
526             __PACKAGE__->has_many('albums' => 'MyApp::Schema::Result::CD', 'album_artist');
527             __PACKAGE__->has_many('cd_artists' => 'MyApp::Schama::Result::CDArtist', 'artistid');
528             __PACKAGE__->belongs_to('producer' => 'MyApp::Schema::Result::Producer', 'producerid');
529             __PACKAGE__->many_to_many('cds' => 'cd_artists', 'cd');
530              
531             package MyApp::Schema::Result::CD;
532             __PACKAGE__->has_many('cd_artists' => 'MyApp::Schema::Result::CDArtist', 'cdid');
533             __PACKAGE__->belongs_to('album_artist' => 'MyApp::Schema::Result::Artist', 'album_artist');
534             __PACKAGE__->many_to_many('artists' => 'cd_artists', 'artist');
535              
536             package MyApp::Schema::Result::CDArtists;
537             __PACKAGE__->belongs_to('cd' => 'MyApp::Schema::Result::CD', 'cdid');
538             __PACKAGE__->belongs_to('artist' => 'MyApp::Schema::Result::Artist', 'artistid');
539              
540             =head4 comma seperated lists
541              
542             Where all related data for individual directly related resultsets are desired
543             then a comma seperated list can be provided to the the prefetch parameter
544              
545             artist/1?prefetch=producer,albums
546              
547             (Note that you can't provide the prefetch parameter multiple times to achieve
548             the same result.)
549              
550             This would return the following JSON+HAL:
551              
552             {
553             artistid: 1,
554             producerid: 1,
555             _embedded: {
556             producer: {
557             producer: id,
558             },
559             albums: [{
560             cdid: 1,
561             album_artist: 1,
562             },{
563             cdid: 2,
564             album_artist: 1,
565             }],
566             },
567             _links: {
568             producer: /producer/1,
569             albums: /artists/1?albums~json={-or: [{cdid: 1}, {cdid: 2}]} # XXX not correct
570             }
571             }
572              
573             =head4 json
574              
575             The C<prefetch> parameter can be specified as a more complex JSON-encoded
576             parameter value. This allows for the full use of prefetch chains.
577             Using key value pairs and lists, prefetches can be nested from one resultset to
578             another:
579              
580             artist/1?prefetch~json={["producer","albums"]}
581              
582             This would produce the same results as above:
583              
584             artist/1?prefetch~json={["producer","cd_artists",{"cds":"album_artist"}]}
585              
586             would producer the following JSON+HAL:
587              
588             {
589             artistid: 1,
590             producerid: 1,
591             _embedded: {
592             producer: {
593             producer: id,
594             },
595             cd_artists: [{
596             artistsid: 1,
597             cdid: 1,
598             _embedded: {
599             cd: {
600             cdid: 1,
601             album_artist: 1,
602             _embedded: {
603             album_artist: {
604             artistid: 1,
605             producerid: 1,
606             },
607             },
608             _links: {
609             /album_artist: /artist/1
610             },
611             },
612             },
613             _links: {
614             cd: /cd/1
615             },
616             }],
617             },
618             _links: {
619             producer: /producer/1,
620             cd_artists: /cdartists?artistid=1&cdid=1,
621             }
622             }
623              
624             NOTE: many_to_many relationships can't be supported as they are not true relationships
625             the related data should be prefetched using the has_many relationship and their join
626             table as in the above example.
627              
628             =head4 where on prefetch
629              
630             The WHERE clause generated can filter results based on related data, as you
631             would expect in a SQL style JOIN. To refer to fields in related resultsets,
632             prefix the name of the field with the name of the relationship:
633              
634             /artist?prefetch=albumns&albums.title='My CD Title'
635              
636             This would return all artists which have an album with the title 'My CD Title'.
637              
638             =head3 fields
639              
640             The fields parameter can be used to limit the fields returned in the response.
641             For example:
642              
643             fields=field1,field2
644              
645             This also works
646             in combination with the prefetch parameter. As with querying on prefetched relations, the
647             relation accessor should be appended before the field name in question.
648              
649             /artist/1?prefetch=albums&fields=artistid,albumns.title
650              
651             For more information on PREFETCHING and JOINS see L<DBIx::Class::Resultset#PREFETCHING>
652              
653             NOTE: DBIx::Class does not support the returning of related data if the relationship
654             accessor for that data matches a column on the requested Set or Item but the fields
655             parameter does not include that column. You must explicitly request fields if prefetching
656             a relation with the same name
657              
658             Using the above example. If the artist has a producer column/field then the following is
659             invalid:
660              
661             /artist/1?prefetch=producer&fields=artistid,producer.producer.producerid
662              
663             but the following is valid:
664              
665             /artist/1?prefetch=producer&fields=artistid,producer,producer.producer.producerid
666              
667             =head3 with
668              
669             The C<with> parameter is used to control optional items within responses. It's
670             a comma separated list of words. This parameter is only passed-through in paging links.
671              
672             * B<count>
673              
674             Adds a C<count> attribute to the C<_meta> hash in the results containing the
675             count of items in the set matched by the request, i.e., the number of items
676             that would be returned if paging was disabled. Also adds a C<last> link to the
677             C<_links> section of the results.
678              
679             * B<nolinks>
680              
681             TBD - possibly used to disable links in the results, especially for large sets
682             of small items where the links section would take significant time and space to
683             construct and return. Might be better as a linkdepth=N where N is decremented
684             at each level of embedding so linkdepth=0 disables all links, but linkdepth=1
685             allows paging of the set but doesn't include links in the embedded resources.
686              
687             =head2 GET on Set
688              
689             GET ~/ecosystems
690              
691             returns
692              
693             {
694             _links: { ... }, # optional
695             _meta: { ... }, # optional
696             _embedded: {
697             ecosystems => [
698             { ... }, ...
699             ]
700             }
701             }
702              
703             The _embedded object contains a key matching the resource name whoose
704             value is an array of those resources, in HAL format. It may seem unusual that
705             the response isn't simply an array of the resources, but you can think of the
706             'set' as a 'virtual' entity that I<contains nothing itself> but just acts as a
707             container, or view, for a set of I<embedded resources>.
708              
709             The _links objects would include links in HAL format for first/prev/next/last.
710              
711             The _meta could include attributes like limit, offset.
712              
713             =head2 GET on Set - Optional Parameters
714              
715             =head3 Paging
716              
717             Set results are returned in pages to prevent accidentally trying to
718             fetch very large numbers of rows. The default is a small number.
719              
720             rows=N - default 30 (at the time of writing)
721             page=N - default 1
722              
723             =head3 fields
724              
725             Partial results, as for GET Item above.
726              
727             =head3 Sorting and Ordering
728              
729             sort=field1
730             sort=field1,-field2
731              
732             A comma-separated list of one or more ordering clauses. Each clause consists of a
733             field designator with an optional C<-> prefix to indicate descending order
734             instead of ascending.
735              
736             Field names can refer to fields of L</prefetch> relations. For example:
737              
738             ~/ecosystems_people?prefetch=person,client_auth&sort=client_auth.username
739              
740             The parameter name C<order> can be used as a deprecated alias for C<sort>.
741             The direction can also be specified by appending either "C< asc>" or "C< desc>"
742             to the field designator. This syntax is deprecated.
743              
744             =head3 Filtering
745              
746             ?me.fieldname=value
747              
748             Filtering with query params
749              
750             ?me.color=red&me.state=running
751              
752             The me.*= values can be JSON data structures if the field name is sufixed with
753             ~json, for example:
754              
755             ?me.color~json=["red","blue"] # would actually be URL encoded
756              
757             which would be evaluated as an SQL 'IN' expression:
758              
759             color IN ('red', 'blue')
760              
761             More complex expressions can be expressed using hashes, for example:
762              
763             ?me.color~json={"like":"%red%"} # would actually be URL encoded
764              
765             would be evaluated as
766              
767             color LIKE '%red%'
768              
769             and
770              
771             ?me.foo~json=[ "-and", {"!=":2}, {"!=":1} ] # shown unencoded
772              
773             would be evaluated as
774              
775             foo != 2 and foo != 1
776              
777             See https://metacpan.org/module/SQL::Abstract#WHERE-CLAUSES for more examples.
778              
779             The me.* parameters are only passed-through in paging links.
780              
781             =head3 Prefetching Related Objects
782              
783             ?prefetch=person,client_auth
784              
785             The resource may have 1-1 and 1-N relationships with other resources.
786             (E.g., "belongs_to" and "has_many" relationships in DBIx::Class terminology.)
787              
788             The relevant instances of related resources can be fetched and returned along
789             with the requested resource by listing the relationships in a prefetch parameter.
790              
791             For example: GET /ecosystems_people?prefetch=person,client_auth
792              
793             {
794             "_links": { ... },
795             "_embedded": {
796             "ecosystems_people": [
797             {
798             "client_auth_id": "29",
799             "person_id": "8",
800             ...
801             "_links": { ... },
802             "_embedded": {
803             "client_auth": { # embedded client_auth resourse
804             "id": 29
805             ...
806             },
807             "person": { # embedded person resourse
808             "id": 8,
809             ...
810             }
811             },
812             },
813             ... # next ecosystems_people resource
814             ]
815             }
816             }
817              
818             =head3 distinct
819              
820             distinct=1
821              
822             Only return distinct results.
823              
824             Currently this parameter requires that both the fields and sort parameters are
825             provided, and have identical values.
826              
827             The results are returned in HAL format, i.e., as an array of objects in an
828             _embedded field, but the objects themselves are not in HAL format, i.e. they
829             don't have _links or _embedded elements.
830              
831             =head2 PUT on Item
832              
833             Update resource attributes using the JSON attribute values in the request body.
834              
835             Embedded related resources can be supplied (if the Content-Type is C<application/hal+json>).
836              
837             Changes will be made in a single transaction.
838              
839             Prefetch of related resources is supported.
840              
841             TODO Enable use of the ETag header for optimistic locking?
842              
843             =head2 PUT on Set
844              
845             Not supported.
846              
847             =head2 DELETE on Item
848              
849             Delete the record.
850              
851             =head2 DELETE on Set
852              
853             Not supported.
854              
855             =head2 POST on Item
856              
857             Not supported.
858              
859             =head2 POST on Set
860              
861             Create a new resource in the set. Returns a 302 redirect with a Location
862             header giving the URL of the newly created resource.
863              
864             Any attributes that aren't specified in the POST data will be given the default
865             values specified by the database schema.
866              
867             The C<prefetch> parameter can be used to request that the created resource
868             (C<prefetch=self>) and any related resources, be returned in the body of the
869             response.
870              
871             The rollback=1 parameter let's you rollback a POST to a set, e.g., for testing.
872              
873             TBD check that only fields valid for GET have been supplied
874              
875             =head2 Creating Related Resources
876              
877             If the Content-Type is C<application/hal+json> then related resources can be
878             provided via the C<_embedded> attribute. They will be created first and the
879             corresponding key fields of the main resource will be set to the appropriate
880             values before it's inserted. All database changes will happen in a single transaction.
881              
882             For example, given a POST to /albums containing:
883              
884             {
885             name: "album name",
886             artist_id: null, # optional
887             _embedded => {
888             artist => {
889             name: "artist name",
890             }
891             }
892             }
893              
894             The artist resource would be created first and its primary key would be
895             used to set the artist_id field before that was created.
896              
897             This process works recursively for any number of level and any number of
898             relations at each level.
899              
900             =head2 Errors
901              
902             Error status responses should include a JSON object with at least these fields:
903              
904             {
905             status: NNN,
906             message: "...",
907             }
908              
909             XXX Needs to be extended to be able to express errors related to specific
910             attributes in the request.
911              
912             The above is out of date. XXX review work on JSON media types for error
913             reporting (I recall there's one that has adopted HAL).
914              
915             =head2 Invoking Methods
916              
917             To enable the execution of functionality not covered by the general HTTP
918             mechanisms described above, it's possible to define resources that represent
919             arbitary methods. These methods are executed by a POST request to the
920             correponding resource. The body of the request contains the parameters to the
921             method.
922              
923             Currently a method can only be invoked on an item resource. The resource for
924             the method call is simply the url of the item resource with '/invoke/:method'
925             appended:
926              
927             POST ~/ecosystems/:id/invoke/:method
928              
929             The request supports the same query parameters as the corresponding item
930             resource.
931              
932             =head3 Default Argument and Response Handling
933              
934             Custom method resources can be defined which can perform any desired action,
935             argument and response handling.
936              
937             A default behaviour is provided to handle simple cases, and that is what is
938             described here.
939              
940             The named method is invoked on the item object specified by the item resource.
941             In other words, the method is a method in the schema's Result class.
942              
943             The POST request must use content-type of application/json and, if arguments
944             are required, are specified via an 'args' element in the body JSON:
945              
946             { args => [ ... ] }
947              
948             The method is called in a scalar context.
949              
950             If the method returns a DBIx::Class::Row object it is returned as a JSON hash.
951              
952             If the method returns a DBIx::Class ResultSet object it is returned as a JSON
953             array containing a hash for every row in the result set. There is no paging.
954              
955             If the method returns any other kind of value it it returned as a JSON hash
956             containing a single element 'result':
957              
958             { result: ... }
959              
960             (To avoid attempting to serialize objects, if the result is blessed then it's
961             stringified.)
962              
963             Note that this default behaviour is liable to change. If you want to make
964             method calls like this you should define your own resource based on the one provided.
965              
966             =head1 AUTHOR
967              
968             Tim Bunce <Tim.Bunce@pobox.com>
969              
970             =head1 COPYRIGHT AND LICENSE
971              
972             This software is copyright (c) 2015 by Tim Bunce.
973              
974             This is free software; you can redistribute it and/or modify it under
975             the same terms as the Perl 5 programming language system itself.
976              
977             =cut