Skip to content

Commit b9d2b17

Browse files
Merge pull request #1780 from bendavies/serializer-listener-performance
Serializer listener performance - anonymous class not serializable
2 parents 70db8df + 010b826 commit b9d2b17

File tree

4 files changed

+99
-14
lines changed

4 files changed

+99
-14
lines changed

src/EventListener/SerializeListener.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace ApiPlatform\Core\EventListener;
1515

1616
use ApiPlatform\Core\Exception\RuntimeException;
17+
use ApiPlatform\Core\Serializer\ResourceList;
1718
use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
1819
use ApiPlatform\Core\Util\RequestAttributesExtractor;
1920
use Symfony\Component\HttpFoundation\Request;
@@ -59,11 +60,7 @@ public function onKernelView(GetResponseForControllerResultEvent $event)
5960
}
6061

6162
$context = $this->serializerContextBuilder->createFromRequest($request, true, $attributes);
62-
$resources = new class() extends \ArrayObject {
63-
public function serialize()
64-
{
65-
}
66-
};
63+
$resources = new ResourceList();
6764
$context['resources'] = &$resources;
6865
$request->attributes->set('_api_normalization_context', $context);
6966

src/Serializer/ResourceList.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
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+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Core\Serializer;
15+
16+
/**
17+
* @internal
18+
*/
19+
class ResourceList extends \ArrayObject
20+
{
21+
public function serialize()
22+
{
23+
}
24+
}

tests/EventListener/SerializeListenerTest.php

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace ApiPlatform\Core\Tests\EventListener;
1515

1616
use ApiPlatform\Core\EventListener\SerializeListener;
17+
use ApiPlatform\Core\Serializer\ResourceList;
1718
use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
1819
use PHPUnit\Framework\TestCase;
1920
use Prophecy\Argument;
@@ -105,11 +106,22 @@ public function testSerializeCollectionOperation()
105106
{
106107
$expectedContext = ['request_uri' => '', 'resource_class' => 'Foo', 'collection_operation_name' => 'get'];
107108
$serializerProphecy = $this->prophesize(SerializerInterface::class);
108-
$serializerProphecy->serialize(Argument::any(), 'xml', Argument::that(function ($context) use ($expectedContext) {
109-
unset($context['resources']);
110109

111-
return $context === $expectedContext;
112-
}))->willReturn('bar')->shouldBeCalled();
110+
$serializerProphecy
111+
->serialize(
112+
Argument::any(),
113+
'xml',
114+
Argument::allOf(
115+
Argument::that(function (array $context) {
116+
return $context['resources'] instanceof ResourceList;
117+
}),
118+
Argument::withEntry('request_uri', ''),
119+
Argument::withEntry('resource_class', 'Foo'),
120+
Argument::withEntry('collection_operation_name', 'get')
121+
)
122+
)
123+
->willReturn('bar')
124+
->shouldBeCalled();
113125

114126
$request = new Request([], [], ['_api_resource_class' => 'Foo', '_api_collection_operation_name' => 'get']);
115127
$request->setRequestFormat('xml');
@@ -130,11 +142,21 @@ public function testSerializeItemOperation()
130142
{
131143
$expectedContext = ['request_uri' => '', 'resource_class' => 'Foo', 'item_operation_name' => 'get'];
132144
$serializerProphecy = $this->prophesize(SerializerInterface::class);
133-
$serializerProphecy->serialize(Argument::any(), 'xml', Argument::that(function ($context) use ($expectedContext) {
134-
unset($context['resources']);
135-
136-
return $context === $expectedContext;
137-
}))->willReturn('bar')->shouldBeCalled();
145+
$serializerProphecy
146+
->serialize(
147+
Argument::any(),
148+
'xml',
149+
Argument::allOf(
150+
Argument::that(function (array $context) {
151+
return $context['resources'] instanceof ResourceList;
152+
}),
153+
Argument::withEntry('request_uri', ''),
154+
Argument::withEntry('resource_class', 'Foo'),
155+
Argument::withEntry('item_operation_name', 'get')
156+
)
157+
)
158+
->willReturn('bar')
159+
->shouldBeCalled();
138160

139161
$request = new Request([], [], ['_api_resource_class' => 'Foo', '_api_item_operation_name' => 'get']);
140162
$request->setRequestFormat('xml');

tests/Serializer/ResourceListTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
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+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Core\Tests\Serializer;
15+
16+
use ApiPlatform\Core\Serializer\ResourceList;
17+
use PHPUnit\Framework\TestCase;
18+
19+
class ResourceListTest extends TestCase
20+
{
21+
/**
22+
* @var ResourceList
23+
*/
24+
private $resourceList;
25+
26+
public function setUp()
27+
{
28+
$this->resourceList = new ResourceList();
29+
}
30+
31+
public function testImplementsArrayObject()
32+
{
33+
$this->assertInstanceOf(\ArrayObject::class, $this->resourceList);
34+
}
35+
36+
public function testSerialize()
37+
{
38+
$this->resourceList['foo'] = 'bar';
39+
40+
$this->assertEquals('N;', \serialize($this->resourceList));
41+
}
42+
}

0 commit comments

Comments
 (0)