The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

JSONAPI::Document - Turn DBIx results into JSON API documents.

VERSION

version 0.9

SYNOPSIS

    use JSONAPI::Document;
    use DBIx::Class::Schema;

    my $jsonapi = JSONAPI::Document->new({ api_url => 'http://example.com/api' });
    my $schema = DBIx::Class::Schema->connect(['dbi:SQLite:dbname=:memory:', '', '']);
    my $user = $schema->resultset('User')->find(1);

    # Builds a simple JSON API document, without any relationships
    my $doc = $jsonapi->resource_document($user);

    # Same but with all relationships
    my $doc = $jsonapi->resource_document($user, { with_relationships => 1 });

    # With only the author relationship
    my $doc = $jsonapi->resource_document($user, { with_relationships => 1, relationships => ['author'] });

    # Fully blown resource document with all relationships and their attributes
    my $doc = $jsonapi->compound_resource_document($user);

    # Multiple resource documents
    my $docs = $jsonapi->resource_documents($schema->resultset('User'));

DESCRIPTION

This is a plug-and-play Moo class that builds data structures according to the JSON API specification.

NOTES

JSON API documents require that you define the type of a document, which this library does using the source_name of the result row. The type is also pluralised using Linua::EN::Inflexion while keeping relationship names intact (i.e. an 'author' relationship will still be called 'author', with the type 'authors').

ATTRIBUTES

api_url

Required; An absolute URL pointing to your servers JSON API namespace.

kebab_case_attrs

Boolean attribute; setting this will make the column keys for each document into kebab-cased-strings instead of snake_cased. Default is false.

attributes_via

The method name to use throughout the creation of the resource document(s) to get the attributes of the resources/relationships. This is useful if you have a object that layers your DBIx results, you can instruct this module to call that method instead of the default, which is get_inflated_columns.

METHODS

compound_resource_document(DBIx::Class::Row|Object $row, HashRef $options)

A compound document is one that includes the resource object along with the data of all its relationships.

Returns a HashRef with the following structure:

    {
        data => {
            id => 1,
            type => 'authors',
            attributes => {},
            relationships => {},
        },
        included => [
            {
                id => 1,
                type => 'posts',
                attributes => { ... },
            },
            ...
        ]
    }

The following options can be given:

includes

An array reference specifying inclusion of a subset of relationships. By default all the relationships will be included, use this if you only want a subset of relationships (e.g. when accepting the includes query parameter in your application routes).

resource_document(DBIx::Class::Row|Object $row, HashRef $options)

Builds a single resource document for the given result row. Will optionally include relationships that contain resource identifiers.

Returns a HashRef with the following structure:

    {
        id => 1,
        type => 'authors',
        attributes => {},
        relationships => {},
    },

View the resource document specification here.

Uses Lingua::EN::Segment to set the appropriate type of the document. This is a bit expensive, but it ensures that your schema results source name gets hyphenated appropriately when converted into its plural form. The resulting type is cached eternally into memory (sorry) to minimize the need to re-compute the document type.

The following options can be given:

with_relationships Bool

If true, will introspect the rows relationships and include each of them in the relationships key of the document.

with_attributes Bool

If with_relationships is true, for each resulting row of a relationship, the attributes of that relation will be included.

By default, each relationship will contain a links object. If this option is true, links object will be replaced with attributes.

includes ArrayRef

If with_relationships is true, this optional array ref can be provided to include a subset of relations instead of all of them.

resource_documents(DBIx::Class::Row|Object $row, HashRef $options)

Builds the structure for multiple resource documents with a given resultset.

Returns a HashRef with the following structure:

    {
        data => [
            {
                id => 1,
                type => 'authors',
                attributes => {},
                relationships => {},
            },
            ...
        ]
    }

See resource_document for a list of options.