Skip to main content

Creating a Response

Every response class must extend AbstractApivalkResponse and implement:
  • getStatusCode(): Returns the HTTP status code (e.g., 200, 201, 404).
  • getDocumentation(): Defines the schema for OpenAPI generation.
  • toArray(): Returns the data to be rendered (usually as JSON).

Example

Resource Responses (CRUD)

When a controller extends one of the Abstract*ResourceController bases, pair it with the matching pre-built response from Http/Response/Resource/: Each wraps the resource’s toArray($mode) output under a data key. ResourceListResponse additionally takes a PaginationResponseInterface and emits the standard pagination envelope. The OpenAPI schema for these responses is generated from the AbstractResource declaration — you do not author response documentation by hand. See Resource Responses.

Built-in Error Responses

Apivalk provides several pre-defined error responses for common scenarios:
  • BadRequestApivalkResponse (400)
  • UnauthorizedApivalkResponse (401)
  • ForbiddenApivalkResponse (403)
  • NotFoundApivalkResponse (404)
  • MethodNotAllowedApivalkResponse (405)
  • TooManyRequestsApivalkResponse (429)
  • InternalServerErrorApivalkResponse (500)
  • BadValidationApivalkResponse (422) - Used automatically by the RequestValidationMiddleware.

Headers

You can add custom headers to any response object:

Automatic Rate Limit Headers

When the Rate Limit Middleware is active, Apivalk automatically appends rate limit information to the response headers. This ensures that clients are always aware of their current quota and remaining requests. The following headers are automatically added:
  • X-RateLimit-Limit: The maximum number of requests allowed in the current window.
  • X-RateLimit-Remaining: The number of requests left for the current window.
  • X-RateLimit-Reset: The time at which the current rate limit window resets (UTC timestamp).
If the rate limit is exceeded (429 Too Many Requests), the Retry-After header is also included.

Pagination

If a route has pagination enabled, you can attach a pagination response object to your response. This will automatically inject the pagination metadata into the JSON output and the OpenAPI documentation.

File Downloads

Return a FileApivalkResponse to stream a file instead of JSON. It always holds a stream, so large files are never loaded into memory as a whole.
Mime detection uses ext-fileinfo and sniffs the content, not the extension. CSV and JSON files are detected as text/plain, so pass the mime type explicitly for those. The response sets Content-Type, Content-Disposition (RFC 6266, UTF-8 file names supported), X-Content-Type-Options: nosniff and, when the stream size is known, Content-Length. The status code is 200. In the OpenAPI document a file response shows up as {type: string, format: binary} under application/octet-stream. To document a specific media type, extend the response and override getDocumentation():

Rendering

The JsonRenderer is the default renderer. It takes the array from toArray() and converts it to a JSON string, handling headers and status codes automatically. $apivalk->getRenderer() routes FileApivalkResponse to the FileStreamRenderer and everything else to the renderer from your configuration. Error responses on a download route (404, 401, 422, …) therefore still render as JSON. If anything was output before the file (a notice, a BOM, a debug echo), the FileStreamRenderer throws a LogicException instead of sending a corrupt download. The stream is closed either way. If output buffering is active (ob_start()), the whole file ends up in the buffer before it is sent. Disable it for download routes when serving large files.