Skip to content

Commit

Permalink
feat!: add schema attributes and reflection of static info
Browse files Browse the repository at this point in the history
  • Loading branch information
lindyhopchris committed Mar 23, 2024
1 parent e8017ef commit 926f5ef
Show file tree
Hide file tree
Showing 23 changed files with 1,291 additions and 209 deletions.
9 changes: 4 additions & 5 deletions src/Contracts/Schema/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

interface Container
{

/**
* Does a schema exist for the supplied resource type?
*
Expand Down Expand Up @@ -43,18 +42,18 @@ public function schemaClassFor(ResourceType|string $type): string;
/**
* Get a schema for the provided model class.
*
* @param string|object $model
* @param class-string|object $model
* @return Schema
*/
public function schemaForModel($model): Schema;
public function schemaForModel(string|object $model): Schema;

/**
* Does a schema exist for the provided model class?
*
* @param string|object $model
* @param class-string|object $model
* @return bool
*/
public function existsForModel($model): bool;
public function existsForModel(string|object $model): bool;

/**
* Get the fully qualified model class for the provided resource type.
Expand Down
26 changes: 2 additions & 24 deletions src/Contracts/Schema/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,12 @@

interface Schema extends Traversable
{

/**
* Get the JSON:API resource type.
*
* @return string
*/
public static function type(): string;

/**
* Get the fully-qualified class name of the model.
*
* @return string
*/
public static function model(): string;

/**
* Get the fully-qualified class name of the resource.
*
* @return string
*/
public static function resource(): string;

/**
* Get the resource type as it appears in URIs.
*
* @return string
* @return non-empty-string
*/
public static function uriType(): string;
public function type(): string;

/**
* Get a repository for the resource.
Expand Down
39 changes: 39 additions & 0 deletions src/Contracts/Schema/StaticSchema/ServerConventions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
/*
* Copyright 2024 Cloud Creativity Limited
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
*/

declare(strict_types=1);

namespace LaravelJsonApi\Contracts\Schema\StaticSchema;

use LaravelJsonApi\Contracts\Schema\Schema;

interface ServerConventions
{
/**
* Resolve the JSON:API resource type for the provided schema.
*
* @param class-string<Schema> $schema
* @return non-empty-string
*/
public function getTypeFor(string $schema): string;

/**
* Resolve the JSON:API resource type as it appears in URIs, for the provided resource type.
*
* @param non-empty-string $type
* @return non-empty-string|null
*/
public function getUriTypeFor(string $type): ?string;

/**
* @param class-string<Schema> $schema
* @return class-string
*/
public function getResourceClassFor(string $schema): string;
}
69 changes: 69 additions & 0 deletions src/Contracts/Schema/StaticSchema/StaticContainer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php
/*
* Copyright 2024 Cloud Creativity Limited
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
*/

declare(strict_types=1);

namespace LaravelJsonApi\Contracts\Schema\StaticSchema;

use IteratorAggregate;
use LaravelJsonApi\Contracts\Schema\Schema;
use LaravelJsonApi\Core\Values\ResourceType;

/**
* @implements IteratorAggregate<StaticSchema>
*/
interface StaticContainer extends IteratorAggregate
{
/**
* Get a static schema for the specified schema class.
*
* @param class-string<Schema>|Schema $schema
* @return StaticSchema
*/
public function schemaFor(string|Schema $schema): StaticSchema;

/**
* Does a schema exist for the supplied JSON:API resource type?
*
* @param ResourceType|non-empty-string $type
* @return bool
*/
public function exists(ResourceType|string $type): bool;

/**
* Get the (non-static) schema class for a JSON:API resource type.
*
* @param ResourceType|non-empty-string $type
* @return class-string<Schema>
*/
public function schemaClassFor(ResourceType|string $type): string;

/**
* Get the fully qualified model class for the provided JSON:API resource type.
*
* @param ResourceType|non-empty-string $type
* @return string
*/
public function modelClassFor(ResourceType|string $type): string;

/**
* Get the JSON:API resource type for the provided type as it appears in URLs.
*
* @param non-empty-string $uriType
* @return ResourceType|null
*/
public function typeForUri(string $uriType): ?ResourceType;

/**
* Get a list of all the supported JSON:API resource types.
*
* @return array<non-empty-string>
*/
public function types(): array;
}
52 changes: 52 additions & 0 deletions src/Contracts/Schema/StaticSchema/StaticSchema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php
/*
* Copyright 2024 Cloud Creativity Limited
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
*/

declare(strict_types=1);

namespace LaravelJsonApi\Contracts\Schema\StaticSchema;

use LaravelJsonApi\Contracts\Schema\Schema;

interface StaticSchema
{
/**
* Get the schema class.
*
* @return class-string<Schema>
*/
public function getSchemaClass(): string;

/**
* Get the JSON:API resource type.
*
* @return non-empty-string
*/
public function getType(): string;

/**
* Get the JSON:API resource type as it appears in URIs.
*
* @return non-empty-string
*/
public function getUriType(): string;

/**
* Get the fully-qualified class name of the model.
*
* @return class-string
*/
public function getModel(): string;

/**
* Get the fully-qualified class name of the resource.
*
* @return class-string
*/
public function getResourceClass(): string;
}
26 changes: 26 additions & 0 deletions src/Contracts/Schema/StaticSchema/StaticSchemaFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php
/*
* Copyright 2024 Cloud Creativity Limited
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
*/

declare(strict_types=1);

namespace LaravelJsonApi\Contracts\Schema\StaticSchema;

use Generator;
use LaravelJsonApi\Contracts\Schema\Schema;

interface StaticSchemaFactory
{
/**
* Make static schemas for the provided schema classes.
*
* @param iterable<class-string<Schema>> $schemas
* @return Generator<StaticSchema>
*/
public function make(iterable $schemas): Generator;
}
11 changes: 2 additions & 9 deletions src/Core/Resources/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,15 @@
use function is_object;
use function sprintf;

class Container implements ContainerContract
final readonly class Container implements ContainerContract
{

/**
* @var Factory
*/
private Factory $factory;

/**
* Container constructor.
*
* @param Factory $factory
*/
public function __construct(Factory $factory)
public function __construct(private Factory $factory)
{
$this->factory = $factory;
}

/**
Expand Down
19 changes: 7 additions & 12 deletions src/Core/Resources/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,21 @@
use LaravelJsonApi\Contracts\Resources\Factory as FactoryContract;
use LaravelJsonApi\Contracts\Schema\Container as SchemaContainer;
use LaravelJsonApi\Contracts\Schema\Schema;
use LaravelJsonApi\Core\Schema\StaticSchema\StaticContainer;
use LogicException;
use Throwable;
use function sprintf;

class Factory implements FactoryContract
final readonly class Factory implements FactoryContract
{

/**
* @var SchemaContainer
*
*/
protected SchemaContainer $schemas;

/**
* Factory constructor.
*
* @param StaticContainer $staticSchemas
* @param SchemaContainer $schemas
*/
public function __construct(SchemaContainer $schemas)
public function __construct(private StaticContainer $staticSchemas, private SchemaContainer $schemas)
{
$this->schemas = $schemas;
}

/**
Expand Down Expand Up @@ -72,9 +66,10 @@ public function createResource(object $model): JsonApiResource
*/
protected function build(Schema $schema, object $model): JsonApiResource
{
$fqn = $schema->resource();
$fqn = $this->staticSchemas
->schemaFor($schema)
->getResourceClass();

return new $fqn($schema, $model);
}

}
27 changes: 27 additions & 0 deletions src/Core/Schema/Attributes/Model.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
/*
* Copyright 2024 Cloud Creativity Limited
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
*/

declare(strict_types=1);

namespace LaravelJsonApi\Core\Schema\Attributes;

use Attribute;

#[Attribute(Attribute::TARGET_CLASS)]
final readonly class Model
{
/**
* Model constructor.
*
* @param class-string $value
*/
public function __construct(public string $value)
{
}
}
27 changes: 27 additions & 0 deletions src/Core/Schema/Attributes/ResourceClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
/*
* Copyright 2024 Cloud Creativity Limited
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
*/

declare(strict_types=1);

namespace LaravelJsonApi\Core\Schema\Attributes;

use Attribute;

#[Attribute(Attribute::TARGET_CLASS)]
final readonly class ResourceClass
{
/**
* ResourceClass constructor.
*
* @param class-string $value
*/
public function __construct(public string $value)
{
}
}
Loading

0 comments on commit 926f5ef

Please sign in to comment.