Catalyst-Controller-DBIC-API

 view release on metacpan or  search on metacpan

lib/Catalyst/Controller/DBIC/API.pm  view on Meta::CPAN

}


sub has_errors {
    my ( $self, $c ) = @_;
    die 'Catalyst app object missing'
        unless defined $c;
    return exists $c->stash->{_dbic_crud_errors};
}


1;

__END__

=pod

=head1 NAME

Catalyst::Controller::DBIC::API - Provides a DBIx::Class web service automagically

=head1 VERSION

version 2.009000

=head1 SYNOPSIS

  package MyApp::Controller::API::RPC::Artist;
  use Moose;
  BEGIN { extends 'Catalyst::Controller::DBIC::API::RPC' }

  __PACKAGE__->config
    ( # define parent chain action and PathPart
      action => {
          setup => {
              Chained  => '/api/rpc/rpc_base',
              PathPart => 'artist',
          }
      },
      class            => 'MyAppDB::Artist',
      resultset_class  => 'MyAppDB::ResultSet::Artist',
      create_requires  => ['name', 'age'],
      create_allows    => ['nickname'],
      update_allows    => ['name', 'age', 'nickname'],
      update_allows    => ['name', 'age', 'nickname'],
      select           => ['name', 'age'],
      prefetch         => ['cds'],
      prefetch_allows  => [
          'cds',
          { cds => 'tracks' },
          { cds => ['tracks'] },
      ],
      ordered_by       => ['age'],
      search_exposes   => ['age', 'nickname', { cds => ['title', 'year'] }],
      data_root        => 'list',
      item_root        => 'data',
      use_json_boolean => 1,
      return_object    => 1,
      );

  # Provides the following functional endpoints:
  # /api/rpc/artist/create
  # /api/rpc/artist/list
  # /api/rpc/artist/id/[id]/delete
  # /api/rpc/artist/id/[id]/update

=head1 DESCRIPTION

Easily provide common API endpoints based on your L<DBIx::Class> schema classes.
Module provides both RPC and REST interfaces to base functionality.
Uses L<Catalyst::Action::Serialize> and L<Catalyst::Action::Deserialize> to
serialize response and/or deserialise request.

=head1 OVERVIEW

This document describes base functionlity such as list, create, delete, update
and the setting of config attributes. L<Catalyst::Controller::DBIC::API::RPC>
and L<Catalyst::Controller::DBIC::API::REST> describe details of provided
endpoints to those base methods.

You will need to create a controller for each schema class you require API
endpoints for. For example if your schema has Artist and Track, and you want to
provide a RESTful interface to these, you should create
MyApp::Controller::API::REST::Artist and MyApp::Controller::API::REST::Track
which both subclass L<Catalyst::Controller::DBIC::API::REST>.
Similarly if you wanted to provide an RPC style interface then subclass
L<Catalyst::Controller::DBIC::API::RPC>. You then configure these individually
as specified in L</CONFIGURATION>.

Also note that the test suite of this module has an example application used to
run tests against. It maybe helpful to look at that until a better tutorial is
written.

=head2 CONFIGURATION

Each of your controller classes needs to be configured to point at the relevant
schema class, specify what can be updated and so on, as shown in the L</SYNOPSIS>.

The class, create_requires, create_allows and update_requires parameters can
also be set in the stash like so:

  sub setup :Chained('/api/rpc/rpc_base') :CaptureArgs(1) :PathPart('any') {
    my ($self, $c, $object_type) = @_;

    if ($object_type eq 'artist') {
      $c->stash->{class} = 'MyAppDB::Artist';
      $c->stash->{create_requires} = [qw/name/];
      $c->stash->{update_allows} = [qw/name/];
    } else {
      $self->push_error($c, { message => "invalid object_type" });
      return;
    }

    $self->next::method($c);
  }

Generally it's better to have one controller for each DBIC source with the
config hardcoded, but in some cases this isn't possible.

Note that the Chained, CaptureArgs and PathPart are just standard Catalyst
configuration parameters and that then endpoint specified in Chained - in this
case '/api/rpc/rpc_base' - must actually exist elsewhere in your application.
See L<Catalyst::DispatchType::Chained> for more details.

Below are explanations for various configuration parameters. Please see
L<Catalyst::Controller::DBIC::API::StaticArguments> for more details.

=head3 class

Whatever you would pass to $c->model to get a resultset for this class.
MyAppDB::Track for example.

=head3 resultset_class

Desired resultset class after accessing your model. MyAppDB::ResultSet::Track
for example. By default, it's DBIx::Class::ResultClass::HashRefInflator.
Set to empty string to leave resultset class without change.

=head3 stash_key

Controls where in stash request_data should be stored, and defaults to 'response'.

=head3 data_root

By default, the response data of multiple item actions is serialized into
$c->stash->{$self->stash_key}->{$self->data_root} and data_root defaults to
'list' to preserve backwards compatibility. This is now configuable to meet
the needs of the consuming client.

=head3 item_root

By default, the response data of single item actions is serialized into
$c->stash->{$self->stash_key}->{$self->item_root} and item_root default to
'data'.

=head3 use_json_boolean

By default, the response success status is set to a string value of "true" or
"false". If this attribute is true, JSON::MaybeXS's true() and false() will be
used instead. Note, this does not effect other internal processing of boolean
values.

=head3 count_arg, page_arg, select_arg, search_arg, grouped_by_arg, ordered_by_arg, prefetch_arg, as_arg, total_entries_arg

These attributes allow customization of the component to understand requests
made by clients where these argument names are not flexible and cannot conform
to this components defaults.

=head3 create_requires

Arrayref listing columns required to be passed to create in order for the
request to be valid.

=head3 create_allows

Arrayref listing columns additional to those specified in create_requires that
are not required to create but which create does allow. Columns passed to create
that are not listed in create_allows or create_requires will be ignored.

=head3 update_allows



( run in 2.145 seconds using v1.01-cache-2.11-cpan-97f6503c9c8 )