Skip to content

Commit 8d8a5c1

Browse files
author
Jérémy Hubert
committed
Ability to add route requirements
Ability to set default route to be used for @id generation
1 parent 15b0ffa commit 8d8a5c1

File tree

5 files changed

+105
-11
lines changed

5 files changed

+105
-11
lines changed

Api/IriConverter.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,18 @@ private function getRouteName(ResourceInterface $resource, $prefix)
141141
return $this->routeCache[$resource][$key];
142142
}
143143

144+
if ($resource instanceof RoutedResourceInterface) {
145+
$method = 'get' . ucfirst($key);
146+
$routeName = $resource->$method();
147+
if ($routeName) {
148+
$data = $this->routeCache[$resource];
149+
$data[$key] = $routeName;
150+
$this->routeCache[$resource] = $data;
151+
152+
return $data[$key];
153+
}
154+
}
155+
144156
$operations = 'item' === $prefix ? $resource->getItemOperations() : $resource->getCollectionOperations();
145157
foreach ($operations as $operation) {
146158
$methods = $operation->getRoute()->getMethods();

Api/Operation/OperationFactory.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class OperationFactory
3939
* @param null $controller
4040
* @param null $routeName
4141
* @param array $context
42+
* @param array $requirements
4243
*
4344
* @return Operation
4445
*/
@@ -48,9 +49,10 @@ public function createCollectionOperation(
4849
$path = null,
4950
$controller = null,
5051
$routeName = null,
51-
array $context = []
52+
array $context = [],
53+
$requirements = []
5254
) {
53-
return $this->createOperation($resource, true, $methods, $path, $controller, $routeName, $context);
55+
return $this->createOperation($resource, true, $methods, $path, $controller, $routeName, $context, $requirements);
5456
}
5557

5658
/**
@@ -62,6 +64,7 @@ public function createCollectionOperation(
6264
* @param null $controller
6365
* @param null $routeName
6466
* @param array $context
67+
* @param array $requirements
6568
*
6669
* @return Operation
6770
*/
@@ -71,9 +74,10 @@ public function createItemOperation(
7174
$path = null,
7275
$controller = null,
7376
$routeName = null,
74-
array $context = []
77+
array $context = [],
78+
$requirements = []
7579
) {
76-
return $this->createOperation($resource, false, $methods, $path, $controller, $routeName, $context);
80+
return $this->createOperation($resource, false, $methods, $path, $controller, $routeName, $context, $requirements);
7781
}
7882

7983
/**
@@ -86,6 +90,7 @@ public function createItemOperation(
8690
* @param string|null $controller
8791
* @param string|null $routeName
8892
* @param array $context
93+
* @param array $requirements
8994
*
9095
* @return Operation
9196
*/
@@ -96,7 +101,8 @@ private function createOperation(
96101
$path = null,
97102
$controller = null,
98103
$routeName = null,
99-
array $context = []
104+
array $context = [],
105+
$requirements = []
100106
) {
101107
$shortName = $resource->getShortName();
102108

@@ -143,7 +149,7 @@ private function createOperation(
143149
'_controller' => $controller,
144150
'_resource' => $shortName,
145151
],
146-
[],
152+
$requirements,
147153
[],
148154
'',
149155
[],

Api/Resource.php

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*
2121
* @author Kévin Dunglas <[email protected]>
2222
*/
23-
class Resource implements ResourceInterface
23+
class Resource implements RoutedResourceInterface
2424
{
2525
/**
2626
* @var string
@@ -54,6 +54,14 @@ class Resource implements ResourceInterface
5454
* @var string|null
5555
*/
5656
private $shortName;
57+
/**
58+
* @var string|null
59+
*/
60+
private $itemRouteName;
61+
/**
62+
* @var string|null
63+
*/
64+
private $collectionRouteName;
5765

5866
/**
5967
* @param string $entityClass
@@ -227,4 +235,36 @@ public function getShortName()
227235
{
228236
return $this->shortName;
229237
}
238+
239+
/**
240+
* {@inheritdoc}
241+
*/
242+
public function getItemRouteName()
243+
{
244+
return $this->itemRouteName;
245+
}
246+
247+
/**
248+
* @param string|null $itemRouteName
249+
*/
250+
public function setItemRouteName($itemRouteName)
251+
{
252+
$this->itemRouteName = $itemRouteName;
253+
}
254+
255+
/**
256+
* {@inheritdoc}
257+
*/
258+
public function getCollectionRouteName()
259+
{
260+
return $this->collectionRouteName;
261+
}
262+
263+
/**
264+
* @param string|null $collectionRouteName
265+
*/
266+
public function setCollectionRouteName($collectionRouteName)
267+
{
268+
$this->collectionRouteName = $collectionRouteName;
269+
}
230270
}

Api/RoutedResourceInterface.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the DunglasApiBundle package.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Dunglas\ApiBundle\Api;
13+
14+
/**
15+
* Class representing an API resource able to specify its item and collection route name.
16+
*
17+
* @author Jérémy Hubert <[email protected]>
18+
*/
19+
interface RoutedResourceInterface extends ResourceInterface
20+
{
21+
/**
22+
* Gets the item route name of the resource (for @id generation).
23+
*
24+
* @return string|null
25+
*/
26+
public function getItemRouteName();
27+
28+
/**
29+
* Gets the collection route name of the resource (for @id generation).
30+
*
31+
* @return string|null
32+
*/
33+
public function getCollectionRouteName();
34+
}

Tests/Api/Operation/OperationFactoryTest.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,18 @@ public function testCreateCollectionOperationWithDefaultValues()
4848
public function testCreateCollectionOperationWithAllParameters()
4949
{
5050
$operation = $this->operationFactory->createCollectionOperation(
51-
$this->resource, ['GET', 'HEAD'], '/bar', 'AppBundle:Test:cget', 'baz', ['kevin' => 'dunglas']
51+
$this->resource, ['GET', 'HEAD'], '/bar/{baz}', 'AppBundle:Test:cget', 'qux', ['kevin' => 'dunglas'], ['baz' => '\d']
5252
);
5353

54-
$this->assertEquals('/bar', $operation->getRoute()->getPath());
54+
$this->assertEquals('/bar/{baz}', $operation->getRoute()->getPath());
5555
$this->assertEquals(['GET', 'HEAD'], $operation->getRoute()->getMethods());
56+
$this->assertArrayHasKey('baz', $operation->getRoute()->getRequirements());
5657

5758
$defaults = $operation->getRoute()->getDefaults();
5859
$this->assertEquals('AppBundle:Test:cget', $defaults['_controller']);
5960
$this->assertEquals('Foo', $defaults['_resource']);
6061

61-
$this->assertEquals('baz', $operation->getRouteName());
62+
$this->assertEquals('qux', $operation->getRouteName());
6263
$this->assertEquals(['kevin' => 'dunglas'], $operation->getContext());
6364
}
6465

@@ -80,11 +81,12 @@ public function testCreateItemOperationWithDefaultValues()
8081
public function testCreateItemOperationWithAllParameters()
8182
{
8283
$operation = $this->operationFactory->createItemOperation(
83-
$this->resource, ['GET', 'HEAD'], '/bar/{id}', 'AppBundle:Test:cget', 'baz', ['kevin' => 'dunglas']
84+
$this->resource, ['GET', 'HEAD'], '/bar/{id}', 'AppBundle:Test:cget', 'baz', ['kevin' => 'dunglas'], ['id' => '\d']
8485
);
8586

8687
$this->assertEquals('/bar/{id}', $operation->getRoute()->getPath());
8788
$this->assertEquals(['GET', 'HEAD'], $operation->getRoute()->getMethods());
89+
$this->assertArrayHasKey('id', $operation->getRoute()->getRequirements());
8890

8991
$defaults = $operation->getRoute()->getDefaults();
9092
$this->assertEquals('AppBundle:Test:cget', $defaults['_controller']);

0 commit comments

Comments
 (0)