Skip to content

Commit 23fdb6e

Browse files
committed
[Feature] Add public API for modifying the request resolver
Implementations should use the new methods on the LaravelJsonApi class to modify the behaviour of the request resolver.
1 parent ce22d74 commit 23fdb6e

File tree

6 files changed

+105
-36
lines changed

6 files changed

+105
-36
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ All notable changes to this project will be documented in this file. This projec
1616
response document. For *to-many* relationships that are countable, this will mean the top-level `meta` member will
1717
contain the count of the relationship.
1818

19+
### Changed
20+
21+
- The `LaravelJsonApi::registerQuery()`, `LaravelJsonApi::registerCollectionQuery()` and
22+
`LaravelJsonApi::registerRequest()` methods must now be used to register custom HTTP request classes for specified
23+
resource types. Previously methods could be called on the `RequestResolver` classes, but these have now been removed.
24+
1925
### Fixed
2026

2127
- Relationship endpoints that return resource identifiers now correctly include page meta in the top-level meta member

src/Http/Requests/RequestResolver.php

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -30,47 +30,37 @@
3030
class RequestResolver
3131
{
3232

33+
public const QUERY = 'Query';
34+
public const COLLECTION_QUERY = 'CollectionQuery';
35+
public const REQUEST = 'Request';
36+
3337
/**
3438
* @var array
3539
*/
3640
private static array $custom = [];
3741

3842
/**
39-
* @var string
43+
* @var array
4044
*/
41-
private string $type;
45+
private static array $defaults = [
46+
self::QUERY => AnonymousQuery::class,
47+
self::COLLECTION_QUERY => AnonymousCollectionQuery::class,
48+
];
4249

4350
/**
44-
* Register a custom binding for a query.
45-
*
46-
* @param string $resourceType
47-
* @param string $class
48-
*/
49-
public static function registerQuery(string $resourceType, string $class): void
50-
{
51-
self::register('Query', $resourceType, $class);
52-
}
53-
54-
/**
55-
* Register a custom binding for a collection query.
56-
*
57-
* @param string $resourceType
58-
* @param string $class
51+
* @var string
5952
*/
60-
public static function registerCollectionQuery(string $resourceType, string $class): void
61-
{
62-
self::register('CollectionQuery', $resourceType, $class);
63-
}
53+
private string $type;
6454

6555
/**
66-
* Register a custom binding for a resource request.
56+
* Use the provided class as the default class for the specified request type.
6757
*
68-
* @param string $resourceType
58+
* @param string $type
6959
* @param string $class
7060
*/
71-
public static function registerRequest(string $resourceType, string $class): void
61+
public static function useDefault(string $type, string $class): void
7262
{
73-
self::register('Request', $resourceType, $class);
63+
self::$defaults[$type] = $class;
7464
}
7565

7666
/**
@@ -80,7 +70,7 @@ public static function registerRequest(string $resourceType, string $class): voi
8070
* @param string $resourceType
8171
* @param string $class
8272
*/
83-
private static function register(string $type, string $resourceType, string $class): void
73+
public static function register(string $type, string $resourceType, string $class): void
8474
{
8575
self::$custom[$type] = self::$custom[$type] ?? [];
8676
self::$custom[$type][$resourceType] = $class;
@@ -113,10 +103,8 @@ public function __invoke(string $resourceType, bool $allowNull = false): ?FormRe
113103
if (!class_exists($fqn) && !$app->bound($fqn)) {
114104
if (true === $allowNull) {
115105
return null;
116-
} else if ('CollectionQuery' === $this->type) {
117-
$fqn = AnonymousCollectionQuery::class;
118-
} else if ('Query' === $this->type) {
119-
$fqn = AnonymousQuery::class;
106+
} else if (isset(self::$defaults[$this->type])) {
107+
$fqn = self::$defaults[$this->type];
120108
}
121109
}
122110

src/Http/Requests/ResourceQuery.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public static function guessQueryManyUsing(callable $resolver): void
7171
*/
7272
public static function queryMany(string $resourceType): QueryParameters
7373
{
74-
$resolver = self::$queryManyResolver ?: new RequestResolver('CollectionQuery');
74+
$resolver = self::$queryManyResolver ?: new RequestResolver(RequestResolver::COLLECTION_QUERY);
7575

7676
return $resolver($resourceType);
7777
}
@@ -95,7 +95,7 @@ public static function guessQueryOneUsing(callable $resolver): void
9595
*/
9696
public static function queryOne(string $resourceType): QueryParameters
9797
{
98-
$resolver = self::$queryManyResolver ?: new RequestResolver('Query');
98+
$resolver = self::$queryManyResolver ?: new RequestResolver(RequestResolver::QUERY);
9999

100100
return $resolver($resourceType);
101101
}

src/Http/Requests/ResourceRequest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public static function guessResourceRequestUsing(callable $resolver): void
6969
*/
7070
public static function forResource(string $resourceType): ResourceRequest
7171
{
72-
$resolver = self::$requestResolver ?: new RequestResolver('Request');
72+
$resolver = self::$requestResolver ?: new RequestResolver(RequestResolver::REQUEST);
7373

7474
return $resolver($resourceType);
7575
}
@@ -82,7 +82,7 @@ public static function forResource(string $resourceType): ResourceRequest
8282
*/
8383
public static function forResourceIfExists(string $resourceType): ?ResourceRequest
8484
{
85-
$resolver = self::$requestResolver ?: new RequestResolver('Request');
85+
$resolver = self::$requestResolver ?: new RequestResolver(RequestResolver::REQUEST);
8686

8787
return $resolver($resourceType, true);
8888
}

src/LaravelJsonApi.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use LaravelJsonApi\Core\Auth\AuthorizerResolver;
2525
use LaravelJsonApi\Core\Query\Custom\ExtendedQueryParameters;
2626
use LaravelJsonApi\Eloquent\Resources\Relation;
27+
use LaravelJsonApi\Laravel\Http\Requests\RequestResolver;
2728

2829
final class LaravelJsonApi
2930
{
@@ -57,6 +58,80 @@ public static function defaultAuthorizer(string $authorizerClass): self
5758
return new self();
5859
}
5960

61+
/**
62+
* Register a HTTP query class for the supplied resource type or types.
63+
*
64+
* @param string $queryClass
65+
* @param $resourceTypes
66+
* @return $this
67+
*/
68+
public static function registerQuery(string $queryClass, $resourceTypes): self
69+
{
70+
foreach (Arr::wrap($resourceTypes) as $resourceType) {
71+
RequestResolver::register(RequestResolver::QUERY, $resourceType, $queryClass);
72+
}
73+
74+
return new self();
75+
}
76+
77+
/**
78+
* Set the default query class implementation.
79+
*
80+
* @param string $queryClass
81+
* @return static
82+
*/
83+
public static function defaultQuery(string $queryClass): self
84+
{
85+
RequestResolver::useDefault(RequestResolver::QUERY, $queryClass);
86+
87+
return new self();
88+
}
89+
90+
/**
91+
* Register a HTTP collection query class for the supplied resource type or types.
92+
*
93+
* @param string $queryClass
94+
* @param $resourceTypes
95+
* @return $this
96+
*/
97+
public static function registerCollectionQuery(string $queryClass, $resourceTypes): self
98+
{
99+
foreach (Arr::wrap($resourceTypes) as $resourceType) {
100+
RequestResolver::register(RequestResolver::COLLECTION_QUERY, $resourceType, $queryClass);
101+
}
102+
103+
return new self();
104+
}
105+
106+
/**
107+
* Set the default collection query class implementation.
108+
*
109+
* @param string $queryClass
110+
* @return static
111+
*/
112+
public static function defaultCollectionQuery(string $queryClass): self
113+
{
114+
RequestResolver::useDefault(RequestResolver::COLLECTION_QUERY, $queryClass);
115+
116+
return new self();
117+
}
118+
119+
/**
120+
* Register a HTTP request class for the supplied resource type or types.
121+
*
122+
* @param string $queryClass
123+
* @param $resourceTypes
124+
* @return $this
125+
*/
126+
public static function registerRequest(string $queryClass, $resourceTypes): self
127+
{
128+
foreach (Arr::wrap($resourceTypes) as $resourceType) {
129+
RequestResolver::register(RequestResolver::REQUEST, $resourceType, $queryClass);
130+
}
131+
132+
return new self();
133+
}
134+
60135
/**
61136
* Set the query parameter name for the countable implementation.
62137
*

tests/dummy/app/JsonApi/V1/Server.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
use App\Models\Video;
2525
use Illuminate\Support\Facades\Auth;
2626
use LaravelJsonApi\Core\Server\Server as BaseServer;
27-
use LaravelJsonApi\Laravel\Http\Requests\RequestResolver;
27+
use LaravelJsonApi\Laravel\LaravelJsonApi;
2828

2929
class Server extends BaseServer
3030
{
@@ -52,7 +52,7 @@ public function serving(): void
5252
$video->owner()->associate(Auth::user());
5353
});
5454

55-
RequestResolver::registerCollectionQuery('media', Media\MediaCollectionQuery::class);
55+
LaravelJsonApi::registerCollectionQuery(Media\MediaCollectionQuery::class, 'media');
5656
}
5757

5858
/**

0 commit comments

Comments
 (0)