czim/laravel-datastore

Laravel data store framework.

2.1.2 2020-05-06 13:35 UTC

This package is auto-updated.

Last update: 2020-10-06 14:33:45 UTC


README

Latest Version on Packagist Software License Build Status Coverage Status

Laravel Datastore

Basic datastore framework for building APIs.

This is intended to be combined with a (JSON-API) transformer/serialization layer.

This approach will allow you to separate responsibilities between serialization and transformation (the API representation layer) and data access abstraction.

Disclaimer

Currently a WIP under heavy development.

Version Compatibility

Laravel Package
5.4 - 5.8 1.1
6.0 2.0+
7.0 2.1

Installation

Via Composer

$ composer require czim/laravel-datastore

Add the DataStoreServiceProvider to your config/app.php:

Czim\DataStore\Providers\DataStoreServiceProvider::class,

Publish the configuration file.

$ php artisan vendor:publish

Filtering

If you intend to make use of the (default) filtering functionality of this package, you should add the czim/laravel-filter dependency:

$ composer require czim/laravel-filter

Documentation

This data store package is split up, responsibility-wise, into two layers: the resource adapter and the data store itself.

A data store is responsible for retrieving and manipulating data. The resource adapter is an interface layer between the data store and the incoming and outgoing data (which can be JSON-API, or any custom transformation/formatting layer that you choose to implement).

Data Stores

Available data stores:

  • \Czim\DataStore\Stores\EloquentDataStore Simple Model data store.

  • \Czim\DataStore\Stores\EloquentDataStore Store to use if you have a repository (Czim\Repository\Contracts\BaseRepositoryInterface) available.

Resource Adapter

This package only provides a resource adapter set-up for JSON-API out of the box, expecting you to use czim/laravel-jsonapi. For any other implementation, you're encouraged to write your own adapter. This package has been designed to make it easy to swap out (custom) implementations, provided some familiarity with Laravel's container and provisioning.

Retrieval Context

The context for retrieving information (filters, sorting, pagination) is defined in interfaces. A RequestContext object may be filled with data in any way, and then passed into the data store to restrict or sort the results. No specific implementation is assumed for this.

Includes

By default, the resource (adapter) and client input determine the includes that will be used for eager loading. Eager loading is then performed on the basis of simple string relation names as with() parameters.

For more flexibility, it is possible to configure include decorators to further control eager loading. To make use of this:

  1. Write an implementation of Czim\DataStore\Contracts\Stores\Includes\IncludeDecoratorInterface.
  2. Configure this class in the datastore.php configuration file:
    • Either as the default include decorator, in datastore.include.decorator.default,
    • or mapped for a specific class under datastore.include.decorator.model-map.<your model class>.

The decorate() method on the decorator will be fed a resolved array of dot-notated include strings, that can be manipulated and returned as desired.

Example:

use Czim\DataStore\Contracts\Stores\Includes\IncludeDecoratorInterface;
use Illuminate\Database\Eloquent\Model;

class CustomIncludeDecorator implements IncludeDecoratorInterface
{
    public function setModel(Model $model)
    {
        // Ignore or store and use the model as desired.
    }

    public function decorate(array $includes, $many = false)
    {
        // Replace a specific include with a closure to eager load with specific columns.
        if (in_array('someRelation', $includes)) {
            $includes = array_diff($includes, ['someRelation']);
            $includes['someRelation'] = function ($query) {
                return $query->select(['id', 'title']);
            };
        }

        // Never eager load a specific relation.
        $includes = array_diff($includes, ['neverEagerLoadThis.relation']);

        // Always eager load some specific relation.
        $includes[] = 'translations';

        return $includes;
    }
}

Contributing

Please see CONTRIBUTING for details.

Credits

License

The MIT License (MIT). Please see License File for more information.