Skip to content

Commit 1985101

Browse files
committed
Allow Response result in a messenger handler
1 parent 0d66a4a commit 1985101

File tree

8 files changed

+134
-2
lines changed

8 files changed

+134
-2
lines changed

features/main/input_output.feature

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ Feature: DTO input and output
246246
Then the response status code should be 201
247247
And the response should be empty
248248

249+
@!mongodb
249250
Scenario: Use messenger with an input where the handler gives a synchronous result
250251
When I add "Content-Type" header equal to "application/ld+json"
251252
And I send a "POST" request to "/messenger_with_inputs" with body:
@@ -267,3 +268,22 @@ Feature: DTO input and output
267268
"name": "test"
268269
}
269270
"""
271+
272+
@!mongodb
273+
Scenario: Use messenger with an input where the handler gives a synchronous Response result
274+
When I add "Content-Type" header equal to "application/ld+json"
275+
And I send a "POST" request to "/messenger_with_responses" with body:
276+
"""
277+
{
278+
"var": "test"
279+
}
280+
"""
281+
Then the response status code should be 200
282+
And the response should be in JSON
283+
And the header "Content-Type" should be equal to "application/json"
284+
And the JSON should be equal to:
285+
"""
286+
{
287+
"data": 123
288+
}
289+
"""

src/Bridge/Symfony/Messenger/DataTransformer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public function supportsTransformation($data, string $to, array $context = []):
4848
if (
4949
\is_object($data) // data is not normalized yet, it should be an array
5050
||
51-
null === $className = $context['input']['class'] ?? null
51+
null === ($context['input']['class'] ?? null)
5252
) {
5353
return false;
5454
}

src/EventListener/RespondListener.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,13 @@ public function onKernelView(GetResponseForControllerResultEvent $event): void
4545
$controllerResult = $event->getControllerResult();
4646
$request = $event->getRequest();
4747

48-
if ($controllerResult instanceof Response || !(($attributes = RequestAttributesExtractor::extractAttributes($request))['respond'] ?? $request->attributes->getBoolean('_api_respond', false))) {
48+
$attributes = RequestAttributesExtractor::extractAttributes($request);
49+
if ($controllerResult instanceof Response && ($attributes['respond'] ?? false)) {
50+
$event->setResponse($controllerResult);
51+
52+
return;
53+
}
54+
if ($controllerResult instanceof Response || !($attributes['respond'] ?? $request->attributes->getBoolean('_api_respond', false))) {
4955
return;
5056
}
5157

tests/EventListener/RespondListenerTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,17 @@ public function testSetCustomStatus()
180180

181181
$this->assertSame(Response::HTTP_ACCEPTED, $event->getResponse()->getStatusCode());
182182
}
183+
184+
public function testHandleResponse()
185+
{
186+
$request = new Request([], [], ['_api_resource_class' => Dummy::class, '_api_item_operation_name' => 'get', '_api_respond' => true]);
187+
$response = new Response();
188+
$eventProphecy = $this->prophesize(GetResponseForControllerResultEvent::class);
189+
$eventProphecy->getControllerResult()->willReturn($response);
190+
$eventProphecy->getRequest()->willReturn($request);
191+
$eventProphecy->setResponse($response)->shouldBeCalled();
192+
193+
$listener = new RespondListener();
194+
$listener->onKernelView($eventProphecy->reveal());
195+
}
183196
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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\Fixtures\TestBundle\Dto;
15+
16+
class MessengerResponseInput
17+
{
18+
/**
19+
* @var string
20+
*/
21+
public $var;
22+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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\Fixtures\TestBundle\Entity;
15+
16+
use ApiPlatform\Core\Annotation\ApiProperty;
17+
use ApiPlatform\Core\Annotation\ApiResource;
18+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Dto\MessengerResponseInput;
19+
20+
/**
21+
* @ApiResource(messenger="input", input=MessengerResponseInput::class)
22+
*/
23+
class MessengerWithResponse
24+
{
25+
/**
26+
* @ApiProperty(identifier=true)
27+
*/
28+
public $id;
29+
/**
30+
* @var string
31+
*/
32+
public $name;
33+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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\Fixtures\TestBundle\MessengerHandler;
15+
16+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Dto\MessengerResponseInput;
17+
use Symfony\Component\HttpFoundation\Response;
18+
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
19+
20+
class MessengerWithResponseHandler implements MessageHandlerInterface
21+
{
22+
public function __invoke(MessengerResponseInput $data)
23+
{
24+
$response = new Response();
25+
$response->setContent(json_encode([
26+
'data' => 123,
27+
]));
28+
$response->headers->set('Content-Type', 'application/json');
29+
30+
return $response;
31+
}
32+
}

tests/Fixtures/app/config/config_common.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,9 @@ services:
244244
public: false
245245
tags:
246246
- { name: 'messenger.message_handler' }
247+
248+
app.messenger_handler.messenger_with_response:
249+
class: 'ApiPlatform\Core\Tests\Fixtures\TestBundle\MessengerHandler\MessengerWithResponseHandler'
250+
public: false
251+
tags:
252+
- { name: 'messenger.message_handler' }

0 commit comments

Comments
 (0)