-
Notifications
You must be signed in to change notification settings - Fork 2
JsonResponse
Pair\Http\JsonResponse is the explicit JSON response object for Pair v4 controllers.
Use it when an action should return a ResponseInterface instead of sending JSON immediately through legacy helpers.
Arguments:
-
payload: JSON payload to emit. Arrays, objects, read models, scalar values, andnullare accepted. -
httpCode: HTTP status code. -
headers: optional additional headers keyed by header name.
Example:
use Pair\Http\JsonResponse;
return new JsonResponse(['saved' => true], 201);With explicit cache headers:
return new JsonResponse(['id' => 7], 200, [
'ETag' => '"abc123"',
'Cache-Control' => 'public, max-age=300',
]);Read-model payloads are converted to arrays before JSON encoding.
Read-model example:
use Pair\Data\ArraySerializableData;
use Pair\Data\ReadModel;
use Pair\Http\JsonResponse;
/**
* Public health payload for an API endpoint.
*/
final readonly class HealthReadModel implements ReadModel {
use ArraySerializableData;
/**
* Build the health payload.
*/
public function __construct(
public bool $ok,
public string $version
) {}
/**
* Export the public health payload.
*
* @return array<string, mixed>
*/
public function toArray(): array {
return [
'ok' => $this->ok,
'version' => $this->version,
];
}
}
return new JsonResponse(new HealthReadModel(true, '4.0.0'), 200);-
send()emitsContent-Type: application/jsonand then any additional headers. Passing aContent-Typeheader replaces the default, which is how Problem Details responses useapplication/problem+json. - Empty payloads keep the historical promotion to HTTP
204. -
send()does not terminate execution by itself; the v4 dispatcher sends the response and then finishes the request. - When
APP_DEBUG=trueand observability debug headers are enabled,send()also emits Pair correlation and trace timing headers. - Legacy
ApiResponse::respond(),error(),success(), andpaginated()still terminate after sending to preserve their old contract.
For Pair v4 web controllers, prefer the helper methods on Pair\Web\Controller when the endpoint should follow the shared JSON conventions:
return $this->dataResponse([
'updatedRows' => 12,
], 'Operation completed.');This emits successful responses with domain data under data and non-domain metadata under meta:
{
"data": {
"updatedRows": 12
},
"meta": {
"message": "Operation completed."
}
}For HTTP errors, use Problem Details:
return $this->problemResponse(
'urn:pair:problem:invalid-request',
'Invalid request',
422,
'The submitted request is missing a required field.',
'INVALID_REQUEST'
);This returns application/problem+json with the RFC 9457 base members plus optional Pair extension members such as code or errors.
Scalar payloads are supported for bridge cases such as idempotency replay:
return new JsonResponse('stored', 200);Normal public API endpoints should still prefer explicit array/object/read-model payloads.
See also: API, ApiResponse, ApiErrorResponse, ReadModel, ResponseInterface, HttpCache, Observability, EmptyResponse, TextResponse.