Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
JsonResponse
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
3 / 3
3
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getPayload
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 withPayload
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5/**
6 * This file is part of php-fast-forward/http-message.
7 *
8 * This source file is subject to the license bundled
9 * with this source code in the file LICENSE.
10 *
11 * @link      https://github.com/php-fast-forward/http-message
12 * @copyright Copyright (c) 2025 Felipe SayĆ£o Lobato Abreu <github@mentordosnerds.com>
13 * @license   https://opensource.org/licenses/MIT MIT License
14 */
15
16namespace FastForward\Http\Message;
17
18use Nyholm\Psr7\Response;
19
20/**
21 * Class JsonResponse.
22 *
23 * Provides a JSON-specific HTTP response implementation that complies with PSR-7 Response interfaces.
24 * This class MUST be used when returning JSON payloads over HTTP responses.
25 * It automatically sets the 'Content-Type' header to 'application/json' with the specified charset.
26 *
27 * @method PayloadStreamInterface getBody() Retrieves the response body as a JSON stream.
28 */
29final class JsonResponse extends Response implements PayloadResponseInterface
30{
31    /**
32     * Constructs a new JsonResponse instance with an optional payload and charset.
33     *
34     * This constructor SHALL initialize the response body with a JsonStream containing the provided payload.
35     * The 'Content-Type' header MUST be set to 'application/json' with the specified charset.
36     *
37     * @param mixed  $payload The JSON-serializable payload to send in the response body. Defaults to an empty array.
38     * @param string $charset The character encoding to use in the 'Content-Type' header. Defaults to 'utf-8'.
39     */
40    public function __construct(
41        mixed $payload = [],
42        string $charset = 'utf-8'
43    ) {
44        parent::__construct(
45            headers: ['Content-Type' => 'application/json; charset=' . $charset],
46            body: new JsonStream($payload),
47        );
48    }
49
50    /**
51     * Retrieves the payload contained in the response body.
52     *
53     * This method MUST return the same payload provided during construction or via withPayload().
54     *
55     * @return mixed the decoded JSON payload
56     */
57    public function getPayload(): mixed
58    {
59        return $this->getBody()->getPayload();
60    }
61
62    /**
63     * Returns an instance with the specified payload.
64     *
65     * This method SHALL return a new instance of the response with the body replaced by a new JsonStream
66     * containing the provided payload. The original instance MUST remain unchanged, ensuring immutability
67     * as required by PSR-7.
68     *
69     * @param mixed $payload the new JSON-serializable payload
70     *
71     * @return self a new JsonResponse instance with the updated payload
72     */
73    public function withPayload(mixed $payload): self
74    {
75        return $this->withBody($this->getBody()->withPayload($payload));
76    }
77}