Skip to content

Commit b0bbab8

Browse files
committed
[Feature] Use relation field URI value for relationship routes
Closes #4
1 parent 03ab622 commit b0bbab8

File tree

7 files changed

+78
-51
lines changed

7 files changed

+78
-51
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ classes you are retaining.
3333
a `v1` server after adding this package to their Laravel application.
3434

3535
### Removed
36-
- **BREAKING** The `Arr` field has been removed - use the new `ArrayList` or `ArrayHash`
36+
- **BREAKING** The `Arr` schema field has been removed - use the new `ArrayList` or `ArrayHash`
3737
fields instead.
38+
- **BREAKING** The `uri` method on relationship routes has been removed. Relationship URIs
39+
are now set on the schema field for the relationship (via the `withUriFieldName` method).
3840

3941
## [1.0.0-alpha.1] - 2021-01-25
4042

src/Routing/PendingRelationshipRegistration.php

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,6 @@ public function __construct(
8282
$this->options = [];
8383
}
8484

85-
/**
86-
* Set the URI for the relationship, if it is not the same as the field name.
87-
*
88-
* @param string $uri
89-
* @return $this
90-
*/
91-
public function uri(string $uri): self
92-
{
93-
$this->options['relationship_uri'] = $uri;
94-
95-
return $this;
96-
}
97-
9885
/**
9986
* Set the methods the controller should apply to.
10087
*

src/Routing/RelationshipRegistrar.php

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Illuminate\Contracts\Routing\Registrar as RegistrarContract;
2323
use Illuminate\Routing\Route as IlluminateRoute;
2424
use Illuminate\Routing\RouteCollection;
25+
use LaravelJsonApi\Contracts\Schema\Schema;
2526
use LaravelJsonApi\Core\Support\Str;
2627

2728
class RelationshipRegistrar
@@ -32,6 +33,11 @@ class RelationshipRegistrar
3233
*/
3334
private RegistrarContract $router;
3435

36+
/**
37+
* @var Schema
38+
*/
39+
private Schema $schema;
40+
3541
/**
3642
* @var string
3743
*/
@@ -51,17 +57,20 @@ class RelationshipRegistrar
5157
* RelationshipRegistrar constructor.
5258
*
5359
* @param RegistrarContract $router
60+
* @param Schema $schema
5461
* @param string $resourceType
5562
* @param string $controller
5663
* @param string $parameter
5764
*/
5865
public function __construct(
5966
RegistrarContract $router,
67+
Schema $schema,
6068
string $resourceType,
6169
string $controller,
6270
string $parameter
6371
) {
6472
$this->router = $router;
73+
$this->schema = $schema;
6574
$this->resourceType = $resourceType;
6675
$this->controller = $controller;
6776
$this->parameter = $parameter;
@@ -95,7 +104,7 @@ public function register(string $fieldName, bool $hasMany, array $options = []):
95104
*/
96105
protected function addShowRelated(string $fieldName, array $options): IlluminateRoute
97106
{
98-
$uri = $this->getRelationshipUri($fieldName, $options);
107+
$uri = $this->getRelationshipUri($fieldName);
99108
$action = $this->getRelationshipAction(
100109
'showRelated',
101110
'showRelated' . Str::classify($fieldName),
@@ -120,7 +129,7 @@ protected function addShowRelated(string $fieldName, array $options): Illuminate
120129
*/
121130
protected function addShowRelationship(string $fieldName, array $options): IlluminateRoute
122131
{
123-
$uri = $this->getRelationshipUri($fieldName, $options);
132+
$uri = $this->getRelationshipUri($fieldName);
124133
$action = $this->getRelationshipAction(
125134
'showRelationship',
126135
'show' . Str::classify($fieldName),
@@ -145,7 +154,7 @@ protected function addShowRelationship(string $fieldName, array $options): Illum
145154
*/
146155
protected function addUpdateRelationship(string $fieldName, array $options): IlluminateRoute
147156
{
148-
$uri = $this->getRelationshipUri($fieldName, $options);
157+
$uri = $this->getRelationshipUri($fieldName);
149158
$action = $this->getRelationshipAction(
150159
'updateRelationship',
151160
'update' . Str::classify($fieldName),
@@ -170,7 +179,7 @@ protected function addUpdateRelationship(string $fieldName, array $options): Ill
170179
*/
171180
protected function addAttachRelationship(string $fieldName, array $options): IlluminateRoute
172181
{
173-
$uri = $this->getRelationshipUri($fieldName, $options);
182+
$uri = $this->getRelationshipUri($fieldName);
174183
$action = $this->getRelationshipAction(
175184
'attachRelationship',
176185
'attach' . Str::classify($fieldName),
@@ -195,7 +204,7 @@ protected function addAttachRelationship(string $fieldName, array $options): Ill
195204
*/
196205
protected function addDetachRelationship(string $fieldName, array $options): IlluminateRoute
197206
{
198-
$uri = $this->getRelationshipUri($fieldName, $options);
207+
$uri = $this->getRelationshipUri($fieldName);
199208
$action = $this->getRelationshipAction(
200209
'detachRelationship',
201210
'detach' . Str::classify($fieldName),
@@ -277,16 +286,11 @@ private function getRelationshipAction(
277286

278287
/**
279288
* @param string $fieldName
280-
* @param array $options
281289
* @return string
282290
*/
283-
private function getRelationshipUri(string $fieldName, array $options): string
291+
private function getRelationshipUri(string $fieldName): string
284292
{
285-
if (isset($options['relationship_uri'])) {
286-
return $options['relationship_uri'];
287-
}
288-
289-
return Str::dasherize($fieldName);
293+
return $this->schema->relationship($fieldName)->uriName();
290294
}
291295

292296
/**

src/Routing/ResourceRegistrar.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,10 @@ public function relationships(
8888

8989
$registrar = new RelationshipRegistrar(
9090
$this->router,
91+
$this->server->schemas()->schemaFor($resourceType),
9192
$resourceType,
9293
$controller,
93-
$parameter
94+
$parameter,
9495
);
9596

9697
$routes = new RouteCollection();

tests/lib/Integration/Routing/HasManyTest.php

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ public function genericProvider(): array
7474
public function test(string $method, string $uri, string $action, string $name): void
7575
{
7676
$server = $this->createServer('v1');
77-
$this->createSchema($server, 'posts', '\d+');
77+
$schema = $this->createSchema($server, 'posts', '\d+');
78+
$this->createRelation($schema, 'tags');
7879

7980
$this->defaultApiRoutesWithNamespace(function () {
8081
JsonApiRoute::server('v1')->prefix('v1')->namespace('Api\\V1')->resources(function ($server) {
@@ -99,13 +100,13 @@ public function test(string $method, string $uri, string $action, string $name):
99100
* @param string $method
100101
* @param string $uri
101102
* @param string $action
102-
* @param string $name
103103
* @dataProvider genericProvider
104104
*/
105-
public function testName(string $method, string $uri, string $action, string $name): void
105+
public function testName(string $method, string $uri, string $action): void
106106
{
107107
$server = $this->createServer('v1');
108-
$this->createSchema($server, 'posts', '\d+');
108+
$schema = $this->createSchema($server, 'posts', '\d+');
109+
$this->createRelation($schema, 'tags');
109110

110111
$this->defaultApiRoutesWithNamespace(function () use ($action) {
111112
JsonApiRoute::server('v1')
@@ -131,7 +132,8 @@ public function testName(string $method, string $uri, string $action, string $na
131132
public function testMiddleware(string $method, string $uri): void
132133
{
133134
$server = $this->createServer('v1');
134-
$this->createSchema($server, 'posts', '\d+');
135+
$schema = $this->createSchema($server, 'posts', '\d+');
136+
$this->createRelation($schema, 'tags');
135137

136138
$this->defaultApiRoutesWithNamespace(function () {
137139
JsonApiRoute::server('v1')
@@ -157,15 +159,16 @@ public function testMiddleware(string $method, string $uri): void
157159
public function testUri(string $method, string $uri): void
158160
{
159161
$server = $this->createServer('v1');
160-
$this->createSchema($server, 'posts', '\d+');
162+
$schema = $this->createSchema($server, 'posts', '\d+');
163+
$this->createRelation($schema, 'blog-tags', 'tags');
161164

162165
$this->defaultApiRoutesWithNamespace(function () {
163166
JsonApiRoute::server('v1')
164167
->prefix('v1')
165168
->namespace('Api\\V1')
166169
->resources(function ($server) {
167170
$server->resource('posts')->relationships(function ($relations) {
168-
$relations->hasMany('blog-tags')->uri('tags');
171+
$relations->hasMany('blog-tags');
169172
});
170173
});
171174
});
@@ -234,7 +237,8 @@ public function onlyProvider(): array
234237
public function testOnly($only, array $matches): void
235238
{
236239
$server = $this->createServer('v1');
237-
$this->createSchema($server, 'posts', '\d+');
240+
$schema = $this->createSchema($server, 'posts', '\d+');
241+
$this->createRelation($schema, 'tags');
238242

239243
$this->defaultApiRoutesWithNamespace(function () use ($only) {
240244
JsonApiRoute::server('v1')
@@ -312,7 +316,8 @@ public function exceptProvider()
312316
public function testExcept($except, array $matches): void
313317
{
314318
$server = $this->createServer('v1');
315-
$this->createSchema($server, 'posts', '\d+');
319+
$schema = $this->createSchema($server, 'posts', '\d+');
320+
$this->createRelation($schema, 'tags');
316321

317322
$this->defaultApiRoutesWithNamespace(function () use ($except) {
318323
JsonApiRoute::server('v1')
@@ -331,7 +336,8 @@ public function testExcept($except, array $matches): void
331336
public function testReadOnly(): void
332337
{
333338
$server = $this->createServer('v1');
334-
$this->createSchema($server, 'posts', '\d+');
339+
$schema = $this->createSchema($server, 'posts', '\d+');
340+
$this->createRelation($schema, 'tags');
335341

336342
$this->defaultApiRoutesWithNamespace(function () {
337343
JsonApiRoute::server('v1')
@@ -403,7 +409,8 @@ public function ownActionProvider(): array
403409
public function testOwnAction(string $method, string $uri, string $action, string $expected): void
404410
{
405411
$server = $this->createServer('v1');
406-
$this->createSchema($server, 'posts', '\d+');
412+
$schema = $this->createSchema($server, 'posts', '\d+');
413+
$this->createRelation($schema, 'tags');
407414

408415
$this->defaultApiRoutesWithNamespace(function () use ($action) {
409416
JsonApiRoute::server('v1')->prefix('v1')->namespace('Api\\V1')->resources(function ($server) use ($action) {
@@ -430,7 +437,8 @@ public function testOwnAction(string $method, string $uri, string $action, strin
430437
public function testOwnActions(string $method, string $uri, string $action, string $expected): void
431438
{
432439
$server = $this->createServer('v1');
433-
$this->createSchema($server, 'posts', '\d+');
440+
$schema = $this->createSchema($server, 'posts', '\d+');
441+
$this->createRelation($schema, 'tags');
434442

435443
$this->defaultApiRoutesWithNamespace(function () {
436444
JsonApiRoute::server('v1')->prefix('v1')->namespace('Api\\V1')->resources(function ($server) {

tests/lib/Integration/Routing/HasOneTest.php

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ public function genericProvider(): array
6262
public function test(string $method, string $uri, string $action, string $name): void
6363
{
6464
$server = $this->createServer('v1');
65-
$this->createSchema($server, 'posts', '\d+');
65+
$schema = $this->createSchema($server, 'posts', '\d+');
66+
$this->createRelation($schema, 'author');
6667

6768
$this->defaultApiRoutesWithNamespace(function () {
6869
JsonApiRoute::server('v1')->prefix('v1')->namespace('Api\\V1')->resources(function ($server) {
@@ -87,13 +88,13 @@ public function test(string $method, string $uri, string $action, string $name):
8788
* @param string $method
8889
* @param string $uri
8990
* @param string $action
90-
* @param string $name
9191
* @dataProvider genericProvider
9292
*/
93-
public function testName(string $method, string $uri, string $action, string $name): void
93+
public function testName(string $method, string $uri, string $action): void
9494
{
9595
$server = $this->createServer('v1');
96-
$this->createSchema($server, 'posts', '\d+');
96+
$schema = $this->createSchema($server, 'posts', '\d+');
97+
$this->createRelation($schema, 'author');
9798

9899
$this->defaultApiRoutesWithNamespace(function () use ($action) {
99100
JsonApiRoute::server('v1')
@@ -121,7 +122,8 @@ public function testName(string $method, string $uri, string $action, string $na
121122
public function testMiddleware(string $method, string $uri, string $action, string $name): void
122123
{
123124
$server = $this->createServer('v1');
124-
$this->createSchema($server, 'posts', '\d+');
125+
$schema = $this->createSchema($server, 'posts', '\d+');
126+
$this->createRelation($schema, 'author');
125127

126128
$this->defaultApiRoutesWithNamespace(function () {
127129
JsonApiRoute::server('v1')
@@ -149,15 +151,16 @@ public function testMiddleware(string $method, string $uri, string $action, stri
149151
public function testUri(string $method, string $uri, string $action, string $name): void
150152
{
151153
$server = $this->createServer('v1');
152-
$this->createSchema($server, 'posts', '\d+');
154+
$schema = $this->createSchema($server, 'posts', '\d+');
155+
$this->createRelation($schema, 'user', 'author');
153156

154157
$this->defaultApiRoutesWithNamespace(function () {
155158
JsonApiRoute::server('v1')
156159
->prefix('v1')
157160
->namespace('Api\\V1')
158161
->resources(function ($server) {
159162
$server->resource('posts')->relationships(function ($relations) {
160-
$relations->hasOne('user')->uri('author');
163+
$relations->hasOne('user');
161164
});
162165
});
163166
});
@@ -203,7 +206,8 @@ public function onlyProvider(): array
203206
public function testOnly($only, array $matches): void
204207
{
205208
$server = $this->createServer('v1');
206-
$this->createSchema($server, 'posts', '\d+');
209+
$schema = $this->createSchema($server, 'posts', '\d+');
210+
$this->createRelation($schema, 'author');
207211

208212
$this->defaultApiRoutesWithNamespace(function () use ($only) {
209213
JsonApiRoute::server('v1')
@@ -258,7 +262,8 @@ public function exceptProvider()
258262
public function testExcept($except, array $matches): void
259263
{
260264
$server = $this->createServer('v1');
261-
$this->createSchema($server, 'posts', '\d+');
265+
$schema = $this->createSchema($server, 'posts', '\d+');
266+
$this->createRelation($schema, 'author');
262267

263268
$this->defaultApiRoutesWithNamespace(function () use ($except) {
264269
JsonApiRoute::server('v1')
@@ -277,7 +282,8 @@ public function testExcept($except, array $matches): void
277282
public function testReadOnly(): void
278283
{
279284
$server = $this->createServer('v1');
280-
$this->createSchema($server, 'posts', '\d+');
285+
$schema = $this->createSchema($server, 'posts', '\d+');
286+
$this->createRelation($schema, 'author');
281287

282288
$this->defaultApiRoutesWithNamespace(function () {
283289
JsonApiRoute::server('v1')
@@ -334,7 +340,8 @@ public function ownActionProvider(): array
334340
public function testOwnAction(string $method, string $uri, string $action, string $expected): void
335341
{
336342
$server = $this->createServer('v1');
337-
$this->createSchema($server, 'posts', '\d+');
343+
$schema = $this->createSchema($server, 'posts', '\d+');
344+
$this->createRelation($schema, 'author');
338345

339346
$this->defaultApiRoutesWithNamespace(function () use ($action) {
340347
JsonApiRoute::server('v1')->prefix('v1')->namespace('Api\\V1')->resources(function ($server) use ($action) {
@@ -361,7 +368,8 @@ public function testOwnAction(string $method, string $uri, string $action, strin
361368
public function testOwnActions(string $method, string $uri, string $action, string $expected): void
362369
{
363370
$server = $this->createServer('v1');
364-
$this->createSchema($server, 'posts', '\d+');
371+
$schema = $this->createSchema($server, 'posts', '\d+');
372+
$this->createRelation($schema, 'author');
365373

366374
$this->defaultApiRoutesWithNamespace(function () {
367375
JsonApiRoute::server('v1')->prefix('v1')->namespace('Api\\V1')->resources(function ($server) {
@@ -377,4 +385,5 @@ public function testOwnActions(string $method, string $uri, string $action, stri
377385
$this->assertSame('post', $route->parameter('resource_id_name'));
378386
$this->assertSame('author', $route->parameter('resource_relationship'));
379387
}
388+
380389
}

tests/lib/Integration/Routing/TestCase.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use Illuminate\Support\Facades\Route;
2525
use LaravelJsonApi\Contracts\Schema\Container;
2626
use LaravelJsonApi\Contracts\Schema\ID;
27+
use LaravelJsonApi\Contracts\Schema\Relation;
2728
use LaravelJsonApi\Contracts\Schema\Schema;
2829
use LaravelJsonApi\Contracts\Server\Repository;
2930
use LaravelJsonApi\Contracts\Server\Server;
@@ -83,6 +84,21 @@ protected function createSchema(Server $server, string $name, string $pattern =
8384
return $schema;
8485
}
8586

87+
/**
88+
* @param MockObject $schema
89+
* @param string $fieldName
90+
* @param string|null $uriName
91+
* @return void
92+
*/
93+
protected function createRelation(MockObject $schema, string $fieldName, string $uriName = null): void
94+
{
95+
$relation = $this->createMock(Relation::class);
96+
$relation->method('name')->willReturn($fieldName);
97+
$relation->method('uriName')->willReturn($uriName ?: $fieldName);
98+
99+
$schema->method('relationship')->with($fieldName)->willReturn($relation);
100+
}
101+
86102
/**
87103
* @param string $method
88104
* @param string $url

0 commit comments

Comments
 (0)