Skip to content

HTTP Responses

Phexium provides a fluent ResponseBuilder for constructing PSR-7 HTTP responses with a clean, chainable API.

PSR-7 Compatibility

Phexium uses PSR-7 HTTP message interfaces (Psr\Http\Message\ServerRequestInterface and Psr\Http\Message\ResponseInterface) throughout its HTTP layer. The implementation is provided by the Nyholm/PSR7 library via the Slim framework, ensuring full interoperability with any PSR-7 compliant library.

Why Use ResponseBuilder

The builder pattern simplifies response construction by handling Content-Type headers automatically and providing a consistent interface across all controllers. Instead of manually writing to response bodies and setting headers, controllers use a declarative approach.

Usage

return $this->responseBuilder
    ->withResponse($response)
    ->withStatus(200)
    ->withHtmlBody($html)
    ->build();

Available Methods

The ResponseBuilderInterface provides:

  • withResponse(ResponseInterface) - Start from the given response (status, headers and body)
  • withStatus(int) - Set HTTP status code
  • withHeader(string, string) - Replace a header value
  • addHeader(string, string) - Append to existing header
  • withRawBody(string, string) - Set a raw body (e.g. binary content) with the given Content-Type
  • withHtmlBody(string) - Set HTML body with text/html Content-Type
  • withJsonBody(array) - Set JSON body with application/json Content-Type
  • build() - Return the final ResponseInterface

The builder is immutable: every method returns a new builder and leaves the current one untouched. The instance shared by the DI container therefore never carries status, headers or body from one response to the next, and build() always creates a fresh response through the PSR-17 ResponseFactoryInterface.

Response Patterns

HTML Response

$html = $this->twig->render('ListBooks.html.twig', (array) $viewModel);

return $this->responseBuilder
    ->withResponse($response)
    ->withHtmlBody($html)
    ->build();

JSON Response

For direct JSON output:

return $this->responseBuilder
    ->withResponse($response)
    ->withJsonBody(['id' => $bookId, 'status' => 'created'])
    ->withStatus(201)
    ->build();

API controllers extending AbstractApiController have helper methods:

return $this->jsonSuccess($response, $data);      // 200 with data
return $this->jsonCreated($response);             // 201
return $this->jsonError($response, 400, 'Error'); // Error with status

Redirect

return $this->responseBuilder
    ->withResponse($response)
    ->withStatus(302)
    ->withHeader('Location', '/books')
    ->build();

Custom Headers

return $this->responseBuilder
    ->withResponse($response)
    ->withHeader('X-Custom-Header', 'value')
    ->addHeader('Cache-Control', 'no-cache')
    ->addHeader('Cache-Control', 'no-store')
    ->withHtmlBody($html)
    ->build();

Common Status Codes

Code Usage
200 Successful GET/display
201 Resource created (API)
302 Redirect after POST
400 Validation errors
401 Authentication required
403 Permission denied
404 Not found

Source Files

  • src/Presentation/ResponseBuilderInterface.php
  • src/Presentation/ResponseBuilder.php

See Also