The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Mojolicious::Plugin::JSONAPI - Mojolicious Plugin for building JSON API compliant applications

VERSION

version 1.6

SYNOPSIS

# Mojolicious

# Using route helpers

sub startup {
    my ($self) = @_;

    $self->plugin('JSONAPI', {
        namespace => 'api',
        data_dir => '/path/to/data/dir',
    });

    $self->resource_routes({
        resource => 'post',
        relationships => ['author', 'comments', 'email-templates'],
    });

    # Now the following routes are available:

    # GET '/api/posts' -> to('api-posts#fetch_posts')
    # POST '/api/posts' -> to('api-posts#post_posts')
    # GET '/api/posts/:post_id -> to('api-posts#get_post')
    # PATCH '/api/posts/:post_id -> to('api-posts#patch_post')
    # DELETE '/api/posts/:post_id -> to('api-posts#delete_post')

    # GET '/api/posts/:post_id/relationships/author' -> to('api-posts#get_related_author')
    # POST '/api/posts/:post_id/relationships/author' -> to('api-posts#post_related_author')
    # PATCH '/api/posts/:post_id/relationships/author' -> to('api-posts#patch_related_author')
    # DELETE '/api/posts/:post_id/relationships/author' -> to('api-posts#delete_related_author')

    # GET '/api/posts/:post_id/relationships/comments' -> to('api-posts#get_related_comments')
    # POST '/api/posts/:post_id/relationships/comments' -> to('api-posts#post_related_comments')
    # PATCH '/api/posts/:post_id/relationships/comments' -> to('api-posts#patch_related_comments')
    # DELETE '/api/posts/:post_id/relationships/comments' -> to('api-posts#delete_related_comments')

    # GET '/api/posts/:post_id/relationships/email-templates' -> to('api-posts#get_related_email_templates')
    # POST '/api/posts/:post_id/relationships/email-templates' -> to('api-posts#post_related_email_templates')
    # PATCH '/api/posts/:post_id/relationships/email-templates' -> to('api-posts#patch_related_email_templates')
    # DELETE '/api/posts/:post_id/relationships/email-templates' -> to('api-posts#delete_related_email_templates')

    # If you're in development mode (e.g. MOJO_MODE eq 'development'), your $app->log will show the created routes. Useful!

    # You can use the following helpers too:

    $self->resource_document($dbic_row, $options);

    $self->compound_resource_document($dbic_row, $options);

    $self->resource_documents($dbic_resultset, $options);
}

DESCRIPTION

This module intends to supply the user with helper methods that can be used to build a JSON API compliant Mojolicious server. It helps create routes for your resources that conform with the specification, along with supplying helper methods to use when responding to requests.

See http://jsonapi.org/ for the JSON API specification. At the time of writing, the version was 1.0.

OPTIONS

HELPERS

resource_routes(HashRef $spec)

Creates a set of routes for the given resource. $spec is a hash reference that can consist of the following:

{
    resource        => 'post', # name of resource, required
    controller      => 'api-posts', # name of controller, defaults to "api-{resource_plural}"
    relationships   => ['author', 'comments'], # default is []
}

render_error(Str $status, ArrayRef|Str $errors, HashRef $data. HashRef $meta)

Renders a JSON response under the required top-level errors key. errors should be an array reference of error objects as described in the specification, or a string that will be the content of title. See Error Objects.

Can optionally provide a reference to the primary data for the route as well as meta information, which will be added to the response as-is. Use resource_document to generate the right structure for this argument.

requested_resources

Convenience helper for controllers. Takes the query param include, used to indicate what relationships to include in the response, and splits it by ',' to return an ArrayRef.

GET /api/posts?include=comments,author
my $include = $c->requested_resources(); # ['comments', 'author']

Can also include nested relationships:

GET /api/posts?include=comments,author.notes
my $include = $c->requested_resources(); # ['comments', { author => ['notes'] }]

NOTE: Only one level of nesting is supported at the moment, so requests like author.notes.notes_relation won't give back what you expect. Stick with author.notes and lazy loading notes_relation.

requested_fields

Takes each query param fields[TYPE] and creates a HashRef containing all its requested fields along with any relationship fields. This is useful if you only want to return a subset of attributes for a resource.

The HashRef produced is suitable to pass directly to the options of JSONAPI::Document::resource_document.

Included fields should be direct attributes of the resource, not its relationships. See requested_resources for that use case.

The main resource should be in the plural form inside the param (i.e. 'posts', not 'post'), and related resources in their correct form.

GET /api/posts?fields[posts]=slug,title&fields[comments]=likes&fields[author]=name,email

my $fields = $c->requested_fields();

# Out:
{
   fields => ['slug', 'title'],
   related_fields => {
       comments => ['likes'],
       author => ['name', 'email']
   }
}

resource_document

Available in controllers:

$c->resource_document($dbix_row, $options);

See resource_document for usage.

compound_resource_document

Available in controllers:

$c->compound_resource_document($dbix_row, $options);

See compound_resource_document for usage.

resource_documents

Available in controllers:

$c->resource_documents($dbix_resultset, $options);

See resource_documents for usage.

LICENSE

This code is available under the Perl 5 License.