10000 [Feature] Allow a custom resolver to be used · AxonDivisionDev/laravel-json-api@f3c858a · GitHub
[go: up one dir, main page]

Skip to content

Commit f3c858a

Browse files
committed
[Feature] Allow a custom resolver to be used
The custom resolver can be used by setting the `resolver` config option to the container binding name that returns a resolver instance. Closes cloudcreativity#123
1 parent 5645cde commit f3c858a

File tree

7 files changed

+261
-11
lines changed

7 files changed

+261
-11
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ relationship request methods.
1212
- [#144](https://github.com/cloudcreativity/laravel-json-api/issues/144)
1313
Improved the helper method that creates new client instances so that it automatically adds a base
1414
URI for the client if one is not provided.
15+
- [#123](https://github.com/cloudcreativity/laravel-json-api/issues/123)
16+
Can now use a custom resolver if wanting to override the default namespace resolution provided by
17+
this package. To do this, set the `resolver` config option to the container binding that returns a
18+
resolver instance.
1519

1620
### Changed
1721
- Extract model sorting from the Eloquent adapter into a `SortsModels` trait.

src/Api/Repository.php

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
namespace CloudCreativity\LaravelJsonApi\Api;
2020

21+
use CloudCreativity\LaravelJsonApi\Contracts\Resolver\ResolverInterface;
2122
use CloudCreativity\LaravelJsonApi\Exceptions\RuntimeException;
2223
use CloudCreativity\LaravelJsonApi\Factories\Factory;
2324
use CloudCreativity\LaravelJsonApi\Resolver\AggregateResolver;
@@ -70,17 +71,7 @@ public function exists($apiName)
7071
public function createApi($apiName, $host = null)
7172
{
7273
$config = $this->configFor($apiName);
73-
$rootNamespace = $this->normalizeRootNamespace(array_get($config, 'namespace'));
74-
$byResource = array_get($config, 'by-resource', true);
75-
$withType = true;
76-
77-
if ('false-0.x' === $byResource) {
78-
$byResource = false;
79-
$withType = false;
80-
}
81-
82-
$resources = (array) array_get($config, 'resources');
83-
$resolver = $this->factory->createResolver($rootNamespace, $resources, (bool) $byResource, $withType);
74+
$resolver = $this->createResolver($config);
8475

8576
$api = new Api(
8677
$this->factory,
@@ -111,6 +102,30 @@ public function createProviders($apiName)
111102
);
112103
}
113104

105+
/**
106+
* @param array $config
107+
* @return ResolverInterface
108+
*/
109+
private function createResolver(array $config)
110+
{
111+
if ($resolver = array_get($config, 'resolver')) {
112+
return $this->factory->createCustomResolver($resolver);
113+
}
114+
115+
$rootNamespace = $this->normalizeRootNamespace(array_get($config, 'namespace'));
116+
$byResource = array_get($config, 'by-resource', true);
117+
$withType = true;
118+
119+
if ('false-0.x' === $byResource) {
120+
$byResource = false;
121+
$withType = false;
122+
}
123+
124+
$resources = (array) array_get($config, 'resources');
125+
126+
return $this->factory->createResolver($rootNamespace, $resources, (bool) $byResource, $withType);
127+
}
128+
114129
/**
115130
* @param $apiName
116131
* @return array

src/Factories/Factory.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,21 @@ public function createResolver($rootNamespace, array $resources, $byResource, $w
9595
return new NamespaceResolver($rootNamespace, $resources, $byResource, $withType);
9696
}
9797

98+
/**
99+
* @param $name
100+
* @return ResolverInterface
101+
*/
102+
public function createCustomResolver($name)
103+
{
104+
$resolver = $this->container->make($name);
105+
106+
if (!$resolver instanceof ResolverInterface) {
107+
throw new \InvalidArgumentException("Container binding {$name} is not a resolver.");
108+
}
109+
110+
return $resolver;
111+
}
112+
98113
/**
99114
* @inheritdoc
100115
*/

stubs/api.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,15 @@
2323
| - e.g. App\JsonApi\Schemas\{PostSchema, CommentSchema}
2424
| - e.g. App\JsonApi\Validators\{PostValidator, CommentValidator}
2525
|
26+
| If you do not want to use our namespace resolution, write your own logic
27+
| in a class that implements
28+
| `CloudCreativity\LaravelJsonApi\Contracts\Resolver\ResolverInterface`.
29+
| Then set the `resolver` option to the container binding that returns your
30+
| implementation.
2631
*/
2732
'namespace' => null,
2833
'by-resource' => true,
34+
'resolver' => null,
2935

3036
/*
3137
|--------------------------------------------------------------------------
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
<?php
2+
3+
namespace CloudCreativity\LaravelJsonApi\Tests\Integration\Resolver;
4+
5+
use CloudCreativity\LaravelJsonApi\Contracts\Resolver\ResolverInterface;
6+
use DummyApp\Post;
7+
8+
class Resolver implements ResolverInterface
9+
{
10+
/**
11+
* @inheritDoc
12+
*/
13+
public function isType($type)
14+
{
15+
return Post::class === $type;
16+
}
17+
18+
/**
19+
* @inheritDoc
20+
*/
21+
public function getType($resourceType)
22+
{
23+
if (!$this->isResourceType($resourceType)) {
24+
throw new \RuntimeException('Unexpected resource type.');
25+
}
26+
27+
return Post::class;
28+
}
29+
30+
/**
31+
* @inheritDoc
32+
*/
33+
public function getAllTypes()
34+
{
35+
return [Post::class];
36+
}
37+
38+
/**
39+
* @inheritDoc
40+
*/
41+
public function isResourceType($resourceType)
42+
{
43+
return 'foobars' === $resourceType;
44+
}
45+
46+
/**
47+
* @inheritDoc
48+
*/
49+
public function getResourceType($type)
50+
{
51+
if (!$this->isType($type)) {
52+
throw new \RuntimeException('Unexpected type.');
53+
}
54+
55+
return 'foobars';
56+
}
57+
58+
/**
59+
* @inheritDoc
60+
*/
61+
public function getAllResourceTypes()
62+
{
63+
return ['foobars'];
64+
}
65+
66+
/**
67+
* @inheritDoc
68+
*/
69+
public function getSchemaByType($type)
70+
{
71+
return "schemas:foobars";
72+
}
73+
74+
/**
75+
* @inheritDoc
76+
*/
77+
public function getSchemaByResourceType($resourceType)
78+
{
79+
return "schemas:foobars";
80+
}
81+
82+
/**
83+
* @inheritDoc
84+
*/
85+
public function getAdapterByType($type)
86+
{
87+
return "adapters:foobars";
88+
}
89+
90+
/**
91+
* @inheritDoc
92+
*/
93+
public function getAdapterByResourceType($resourceType)
94+
{
95+
return "adapters:foobars";
96+
}
97+
98+
/**
99+
* @inheritDoc
100+
*/
101+
public function getAuthorizerByType($type)
102+
{
103+
return 'authorizers:foobars';
104+
}
105+
106+
/**
107+
* @inheritDoc
108+
*/
109+
public function getAuthorizerByResourceType($resourceType)
110+
{
111+
return 'authorizers:foobars';
112+
}
113+
114+
/**
115+
* @inheritDoc
116+
*/
117+
public function getAuthorizerByName($name)
118+
{
119+
return "authorizers:{$name}";
120+
}
121+
122+
/**
123+
* @inheritDoc
124+
*/
125+
public function getValidatorsByType($type)
126+
{
127+
return "validators:foobars";
128+
}
129+
130+
/**
131+
* @inheritDoc
132+
*/
133+
public function getValidatorsByResourceType($resourceType)
134+
{
135+
return "validators:foobars";
136+
}
137+
138+
}
< F438 div class="d-flex mr-2 flex-justify-end flex-items-center flex-1">
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
namespace CloudCreativity\LaravelJsonApi\Tests\Integration\Resolver;
4+
5+
use CloudCreativity\LaravelJsonApi\Facades\JsonApi;
6+
use CloudCreativity\LaravelJsonApi\Routing\ApiGroup;
7+
use CloudCreativity\LaravelJsonApi\Tests\Integration\TestCase;
8+
use DummyApp\JsonApi\Posts\Adapter;
9+
use DummyApp\Post;
10+
use Illuminate\Support\Facades\Route;
11+
12+
class ResolverTest extends TestCase
13+
{
14+
15+
/**
16+
* @var string
17+
*/
18+
protected $resourceType = 'foobars';
19+
20+
/**
21+
* @var bool
22+
*/
23+
protected $appRoutes = false;
24+
25+
/**
26+
* @return void
27+
*/
28+
protected function setUp()
29+
{
30+
parent::setUp();
31+
32+
$this->app->bind('adapters:foobars', Adapter::class);
33+
$this->app->bind('schemas:foobars', Schema::class);
34+
35+
Route::group([
36+
'namespace' => 'DummyApp\\Http\\Controllers',
37+
], function () {
38+
JsonApi::register('v1', [], function (ApiGroup $api) {
39+
$api->resource('foobars');
40+
});
41+
});
42+
43+
config()->set('json-api-v1.resolver', Resolver::class);
44+
}
45+
46+
public function test()
47+
{
48+
$post = factory(Post::class)->create();
49+
50+
$this->doRead($post)->assertRead([
51+
'type' => 'foobars',
52+
'id' => $post->getRouteKey(),
53+
'attributes' => [
54+
'title' => $post->title,
55+
],
56+
]);
57+
}
58+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace CloudCreativity\LaravelJsonApi\Tests\Integration\Resolver;
4+
5+
use DummyApp\JsonApi\Posts\Schema as BaseSchema;
6+
7+
class Schema extends BaseSchema
8+
{
9+
10+
/**
11+
* @var string
12+
*/
13+
protected $resourceType = 'foobars';
14+
}

0 commit comments

Comments
 (0)
0