Skip to content

Commit 4af4429

Browse files
feat(router): json serializable as response body (#1420)
1 parent d25bc44 commit 4af4429

File tree

8 files changed

+38
-7
lines changed

8 files changed

+38
-7
lines changed

packages/http/src/GenericResponse.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Tempest\Http;
66

77
use Generator;
8+
use JsonSerializable;
89
use Tempest\View\View;
910

1011
final class GenericResponse implements Response
@@ -13,7 +14,7 @@ final class GenericResponse implements Response
1314

1415
public function __construct(
1516
Status $status,
16-
Generator|View|string|array|null $body = null,
17+
Generator|View|string|array|JsonSerializable|null $body = null,
1718
array $headers = [],
1819
?View $view = null,
1920
) {

packages/http/src/IsResponse.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Tempest\Http;
66

77
use Generator;
8+
use JsonSerializable;
89
use Tempest\Http\Cookie\Cookie;
910
use Tempest\Http\Cookie\CookieManager;
1011
use Tempest\Http\Session\Session;
@@ -17,7 +18,7 @@ trait IsResponse
1718
{
1819
private(set) Status $status = Status::OK;
1920

20-
private(set) View|string|array|Generator|null $body = null;
21+
private(set) View|string|array|Generator|JsonSerializable|null $body = null;
2122

2223
/** @var \Tempest\Http\Header[] */
2324
private(set) array $headers = [];

packages/http/src/Response.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Tempest\Http;
66

77
use Generator;
8+
use JsonSerializable;
89
use Tempest\Http\Cookie\Cookie;
910
use Tempest\View\View;
1011

@@ -19,7 +20,7 @@ interface Response
1920
get;
2021
}
2122

22-
public View|string|array|Generator|null $body {
23+
public View|string|array|Generator|JsonSerializable|null $body {
2324
get;
2425
}
2526

packages/http/src/Responses/Created.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Tempest\Http\Responses;
66

7+
use JsonSerializable;
78
use Tempest\Http\IsResponse;
89
use Tempest\Http\Response;
910
use Tempest\Http\Status;
@@ -13,7 +14,7 @@ final class Created implements Response
1314
{
1415
use IsResponse;
1516

16-
public function __construct(string|array|null|View $body = null)
17+
public function __construct(string|array|null|View|JsonSerializable $body = null)
1718
{
1819
$this->status = Status::CREATED;
1920
$this->body = $body;

packages/http/src/Responses/NotFound.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Tempest\Http\Responses;
66

77
use Generator;
8+
use JsonSerializable;
89
use Tempest\Http\IsResponse;
910
use Tempest\Http\Response;
1011
use Tempest\Http\Status;
@@ -14,7 +15,7 @@ final class NotFound implements Response
1415
{
1516
use IsResponse;
1617

17-
public function __construct(View|Generator|string|array|null $body = null)
18+
public function __construct(View|JsonSerializable|Generator|string|array|null $body = null)
1819
{
1920
$this->status = Status::NOT_FOUND;
2021
$this->body = $body;

packages/http/src/Responses/Ok.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Tempest\Http\Responses;
66

77
use Generator;
8+
use JsonSerializable;
89
use Tempest\Http\IsResponse;
910
use Tempest\Http\Response;
1011
use Tempest\Http\Status;
@@ -14,7 +15,7 @@ final class Ok implements Response
1415
{
1516
use IsResponse;
1617

17-
public function __construct(View|Generator|string|array|null $body = null)
18+
public function __construct(View|JsonSerializable|Generator|string|array|null $body = null)
1819
{
1920
$this->status = Status::OK;
2021
$this->body = $body;

packages/router/src/GenericResponseSender.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Tempest\Router;
66

77
use Generator;
8+
use JsonSerializable;
89
use Tempest\Container\Container;
910
use Tempest\Http\ContentType;
1011
use Tempest\Http\Header;
@@ -96,7 +97,7 @@ private function sendContent(Response $response): void
9697

9798
if ($response instanceof File || $response instanceof Download) {
9899
readfile($body);
99-
} elseif (is_array($body)) {
100+
} elseif (is_array($body) || $body instanceof JsonSerializable) {
100101
echo json_encode($body);
101102
} elseif ($body instanceof View) {
102103
echo $this->viewRenderer->render($body);

tests/Integration/Http/GenericResponseSenderTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Tests\Tempest\Integration\Http;
66

7+
use JsonSerializable;
78
use Tempest\Http\GenericRequest;
89
use Tempest\Http\GenericResponse;
910
use Tempest\Http\Method;
@@ -127,6 +128,29 @@ public function test_sending_of_array_to_json(): void
127128
$this->assertSame('{"key":"value"}', $output);
128129
}
129130

131+
public function test_sending_of_json_serializable_to_json(): void
132+
{
133+
ob_start();
134+
135+
$response = new GenericResponse(
136+
status: Status::CREATED,
137+
body: new class implements JsonSerializable {
138+
public function jsonSerialize(): mixed
139+
{
140+
return ['key' => 'value'];
141+
}
142+
},
143+
);
144+
145+
$responseSender = $this->container->get(GenericResponseSender::class);
146+
147+
$responseSender->send($response);
148+
149+
$output = ob_get_clean();
150+
151+
$this->assertSame('{"key":"value"}', $output);
152+
}
153+
130154
public function test_view_body(): void
131155
{
132156
ob_start();

0 commit comments

Comments
 (0)