Skip to content
neomerx edited this page Feb 5, 2019 · 8 revisions

Package Extension

This package is designed to be highly modular. Package parts are connected to each other with interfaces so you can easily replace those parts with your implementations.

Let's illustrate the approach by example. Suppose your schema returns an object with a subclass of the expected class.

class PostSchema extends BaseSchema
{
    ...

    public function getRelationships($post): iterable
    {
        return [
            'author' => [
                // will not return an Author object but
                // AuthorProxy which extends Author
                self::RELATIONSHIP_DATA => $post->getAuthor() 
            ]
        ];
    }
    
    ...
}

For this case there is a quick fix (below) however let's see how Container class could be extended

// quick fix
$encoder = Encoder::instance([
    Author::class       => AuthorSchema::class,
    AuthorProxy::class  => AuthorSchema::class,
]);

Main Steps

  • Inherit Container and override required method (getResourceType in our case)
  • Inherit Factory and override createSchemaContainer method
  • Inherit Encoder and override createFactory and return the new schema factory instance

Implementation

use Doctrine\Common\Util\ClassUtils;
use Neomerx\JsonApi\Encoder\Encoder;
use Neomerx\JsonApi\Schema\SchemaContainer;
use Neomerx\JsonApi\Factories\Factory;

class YourContainer extends SchemaContainer
{
    protected function getResourceType($resource)
    {
        return ClassUtils::getRealClass(get_class($resource));
    }
}

class YourFactory extends Factory
{
    public function createSchemaContainer(iterable $schemas): SchemaContainerInterface
    {
        return new YourContainer($this, $schemas);
    }
}

class YourEncoder extends Encoder
{
    protected static function createFactory(): FactoryInterface
    {
        return new YourFactory();
    }
}

This topic is based on #40 and refactored in #44.

Clone this wiki locally