Skip to content

Commit 37e70a0

Browse files
committed
Refactor RequestAttributesExtractor to not throw on the hot path
1 parent 9f0b155 commit 37e70a0

File tree

8 files changed

+27
-58
lines changed

8 files changed

+27
-58
lines changed

src/Bridge/FosUser/EventListener.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
namespace ApiPlatform\Core\Bridge\FosUser;
1313

14-
use ApiPlatform\Core\Exception\RuntimeException;
1514
use ApiPlatform\Core\Util\RequestAttributesExtractor;
1615
use FOS\UserBundle\Model\UserInterface;
1716
use FOS\UserBundle\Model\UserManagerInterface;
@@ -41,9 +40,7 @@ public function __construct(UserManagerInterface $userManager)
4140
public function onKernelView(GetResponseForControllerResultEvent $event)
4241
{
4342
$request = $event->getRequest();
44-
try {
45-
RequestAttributesExtractor::extractAttributes($request);
46-
} catch (RuntimeException $e) {
43+
if (!RequestAttributesExtractor::extractAttributes($request)) {
4744
return;
4845
}
4946

src/Bridge/Symfony/Validator/EventListener/ValidateListener.php

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
namespace ApiPlatform\Core\Bridge\Symfony\Validator\EventListener;
1313

1414
use ApiPlatform\Core\Bridge\Symfony\Validator\Exception\ValidationException;
15-
use ApiPlatform\Core\Exception\RuntimeException;
1615
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
1716
use ApiPlatform\Core\Util\RequestAttributesExtractor;
1817
use Symfony\Component\HttpFoundation\Request;
@@ -45,17 +44,12 @@ public function __construct(ValidatorInterface $validator, ResourceMetadataFacto
4544
public function onKernelView(GetResponseForControllerResultEvent $event)
4645
{
4746
$request = $event->getRequest();
48-
if ($request->isMethodSafe(false) || $request->isMethod(Request::METHOD_DELETE)) {
49-
return;
50-
}
51-
52-
try {
53-
$attributes = RequestAttributesExtractor::extractAttributes($request);
54-
} catch (RuntimeException $e) {
55-
return;
56-
}
57-
58-
if (!$attributes['receive']) {
47+
if (
48+
$request->isMethodSafe(false)
49+
|| $request->isMethod(Request::METHOD_DELETE)
50+
|| !($attributes = RequestAttributesExtractor::extractAttributes($request))
51+
|| !$attributes['receive']
52+
) {
5953
return;
6054
}
6155

src/EventListener/DeserializeListener.php

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
namespace ApiPlatform\Core\EventListener;
1313

14-
use ApiPlatform\Core\Exception\RuntimeException;
1514
use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
1615
use ApiPlatform\Core\Util\RequestAttributesExtractor;
1716
use Symfony\Component\HttpFoundation\Request;
@@ -45,17 +44,12 @@ public function __construct(SerializerInterface $serializer, SerializerContextBu
4544
public function onKernelRequest(GetResponseEvent $event)
4645
{
4746
$request = $event->getRequest();
48-
if ($request->isMethodSafe(false) || $request->isMethod(Request::METHOD_DELETE)) {
49-
return;
50-
}
51-
52-
try {
53-
$attributes = RequestAttributesExtractor::extractAttributes($request);
54-
} catch (RuntimeException $e) {
55-
return;
56-
}
57-
58-
if (!$attributes['receive']) {
47+
if (
48+
$request->isMethodSafe(false)
49+
|| $request->isMethod(Request::METHOD_DELETE)
50+
|| !($attributes = RequestAttributesExtractor::extractAttributes($request))
51+
|| !$attributes['receive']
52+
) {
5953
return;
6054
}
6155

src/EventListener/ReadListener.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
1515
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
1616
use ApiPlatform\Core\DataProvider\PaginatorInterface;
17-
use ApiPlatform\Core\Exception\RuntimeException;
1817
use ApiPlatform\Core\Util\RequestAttributesExtractor;
1918
use Symfony\Component\HttpFoundation\Request;
2019
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
@@ -46,13 +45,10 @@ public function __construct(CollectionDataProviderInterface $collectionDataProvi
4645
public function onKernelRequest(GetResponseEvent $event)
4746
{
4847
$request = $event->getRequest();
49-
try {
50-
$attributes = RequestAttributesExtractor::extractAttributes($request);
51-
} catch (RuntimeException $e) {
52-
return;
53-
}
54-
55-
if (!$attributes['receive']) {
48+
if (
49+
!($attributes = RequestAttributesExtractor::extractAttributes($request))
50+
|| !$attributes['receive']
51+
) {
5652
return;
5753
}
5854

src/EventListener/SerializeListener.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ public function onKernelView(GetResponseForControllerResultEvent $event)
5050
return;
5151
}
5252

53-
try {
54-
$attributes = RequestAttributesExtractor::extractAttributes($request);
55-
} catch (RuntimeException $e) {
53+
if (!$attributes = RequestAttributesExtractor::extractAttributes($request)) {
5654
$this->serializeRawData($event, $request, $controllerResult);
5755

5856
return;

src/Serializer/SerializerContextBuilder.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace ApiPlatform\Core\Serializer;
1313

14+
use ApiPlatform\Core\Exception\RuntimeException;
1415
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
1516
use ApiPlatform\Core\Util\RequestAttributesExtractor;
1617
use Symfony\Component\HttpFoundation\Request;
@@ -34,8 +35,8 @@ public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFa
3435
*/
3536
public function createFromRequest(Request $request, bool $normalization, array $attributes = null): array
3637
{
37-
if (null === $attributes) {
38-
$attributes = RequestAttributesExtractor::extractAttributes($request);
38+
if (null === $attributes && !$attributes = RequestAttributesExtractor::extractAttributes($request)) {
39+
throw new RuntimeException('Request attributes are not valid.');
3940
}
4041

4142
$resourceMetadata = $this->resourceMetadataFactory->create($attributes['resource_class']);

src/Util/RequestAttributesExtractor.php

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
namespace ApiPlatform\Core\Util;
1313

14-
use ApiPlatform\Core\Exception\RuntimeException;
1514
use Symfony\Component\HttpFoundation\Request;
1615

1716
/**
@@ -28,21 +27,19 @@ private function __construct()
2827
}
2928

3029
/**
31-
* Extracts resource class, operation name and format request attributes. Throws an exception if the request does not
32-
* contain required attributes.
30+
* Extracts resource class, operation name and format request attributes. Returns an empty array if the request does
31+
* not contain required attributes.
3332
*
3433
* @param Request $request
3534
*
36-
* @throws RuntimeException
37-
*
3835
* @return array
3936
*/
4037
public static function extractAttributes(Request $request)
4138
{
4239
$result = ['resource_class' => $request->attributes->get('_api_resource_class')];
4340

4441
if (null === $result['resource_class']) {
45-
throw new RuntimeException('The request attribute "_api_resource_class" must be defined.');
42+
return [];
4643
}
4744

4845
$collectionOperationName = $request->attributes->get('_api_collection_operation_name');
@@ -53,7 +50,7 @@ public static function extractAttributes(Request $request)
5350
} elseif ($itemOperationName) {
5451
$result['item_operation_name'] = $itemOperationName;
5552
} else {
56-
throw new RuntimeException('One of the request attribute "_api_collection_operation_name" or "_api_item_operation_name" must be defined.');
53+
return [];
5754
}
5855

5956
if (null === $apiRequest = $request->attributes->get('_api_receive')) {

tests/Util/RequestAttributesExtractorTest.php

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,21 +63,13 @@ public function testExtractReceive()
6363
);
6464
}
6565

66-
/**
67-
* @expectedException \ApiPlatform\Core\Exception\RuntimeException
68-
* @expectedExceptionMessage The request attribute "_api_resource_class" must be defined.
69-
*/
7066
public function testResourceClassNotSet()
7167
{
72-
RequestAttributesExtractor::extractAttributes(new Request([], [], ['_api_item_operation_name' => 'get']));
68+
$this->assertEmpty(RequestAttributesExtractor::extractAttributes(new Request([], [], ['_api_item_operation_name' => 'get'])));
7369
}
7470

75-
/**
76-
* @expectedException \ApiPlatform\Core\Exception\RuntimeException
77-
* @expectedExceptionMessage One of the request attribute "_api_collection_operation_name" or "_api_item_operation_name" must be defined.
78-
*/
7971
public function testOperationNotSet()
8072
{
81-
RequestAttributesExtractor::extractAttributes(new Request([], [], ['_api_resource_class' => 'Foo']));
73+
$this->assertEmpty(RequestAttributesExtractor::extractAttributes(new Request([], [], ['_api_resource_class' => 'Foo'])));
8274
}
8375
}

0 commit comments

Comments
 (0)