Responses
Every route declares exactly one response type. Gustav and PSR-7 response
objects pass through unchanged, View responses render as HTML, and other
supported declared types are serialized as JSON.
Typed JSON
Return a DTO, array, scalar, backed enum, or nullable value directly:
use GustavPHP\Gustav\Attribute\Get;
final readonly class DogOutput
{
public function __construct(
public int $id,
public string $name,
) {
}
}
#[Get('/dogs/{id}')]
public function show(): DogOutput
{
return new DogOutput(42, 'Rex');
}
Gustav returns status 200, supplies Content-Type: application/json, and recursively normalizes the value. See Serialization for supported values, readonly DTOs, enums, exclusions, and failure behavior.
Views
Return a View directly from a plain controller to render a native PHP
template:
use GustavPHP\Gustav\View;
#[Get]
public function index(): View
{
return new View('home', ['title' => 'Gustav']);
}
The response uses text/html; charset=utf-8. Views can also carry a custom
status and headers. See Views for typed view models, escaping,
layouts, partials, and renderer replacement.
Controllers extending Controller\Base can use the following protected
response helpers.
HTML
Controllers extending Controller\Base can use html() to return HTML content:
#[Get('/html')]
public function index(): Controller\Response
{
return $this->html('<h1>Hello World!</h1>');
}
JSON helper
Use json() when the body is selected dynamically or the response needs a non-default status or custom headers:
use GustavPHP\Gustav\Attribute\Post;
#[Post('/dogs')]
public function create(): Controller\Response
{
return $this->json([
'name' => 'Rex',
'age' => 4,
], status: 201, headers: ['X-Resource-Type' => 'dog']);
}
Plain text
Use plaintext() for a text response:
return $this->plaintext('ready');
XML
Use xml() for XML content:
return $this->xml('<status>ready</status>');
Redirect
Use redirect() with a destination and, optionally, a status:
return $this->redirect('/dogs');
PSR-7 response
A controller may return a PSR-7 response directly:
use GustavPHP\Gustav\Attribute\Get;
use Nyholm\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
#[Get('/accepted')]
public function accepted(): ResponseInterface
{
return new Response(202, ['Content-Type' => 'text/plain'], 'accepted');
}
Errors
See Errors for HTTP exceptions, request and validation errors,
production-safe 500 responses, and request IDs.