Skip to content

Responses ​

Lalaz provides several ways to send HTTP responses from your controllers. You can return arrays (automatically converted to JSON), use the Response object for full control, or use helper functions for common response types.

Returning Arrays ​

The simplest way to return JSON is to return an array from your controller:

php
public function index(): array
{
    return [
        'users' => [],
        'count' => 0,
    ];
}

This automatically sends a JSON response with status code 200 and Content-Type: application/json.

JSON Helper Functions ​

Use the global helper functions for JSON responses:

json() ​

Create a JSON response with optional status code:

php
use function json;

public function index(): mixed
{
    return json(['users' => []], 200);
}

public function store(): mixed
{
    return json(['id' => 1, 'name' => 'John'], 201);
}

json_success() ​

Create a standardized success response:

php
use function json_success;

public function update(): mixed
{
    return json_success(['user' => $user], 'User updated successfully');
}
// Returns: {"success": true, "message": "User updated successfully", "data": {"user": {...}}}

json_error() ​

Create a standardized error response:

php
use function json_error;

public function store(): mixed
{
    return json_error('Validation failed', 422, [
        'email' => 'Invalid email address',
        'name' => 'Name is required',
    ]);
}
// Returns: {"success": false, "message": "Validation failed", "errors": {"email": "...", "name": "..."}}

Using the Response Object ​

For more control, inject the Response object:

php
use Lalaz\Web\Http\Response;

public function index(Response $response): void
{
    $response->json(['users' => []], 200);
}

Setting Status Code ​

php
$response->status(201);
$response->status(404);
$response->status(500);

Setting Headers ​

php
// Single header
$response->header('X-Custom-Header', 'value');

// Multiple headers
$response->withHeaders([
    'X-Custom-Header' => 'value',
    'X-Another-Header' => 'another-value',
]);

JSON Response ​

php
$response->json(['key' => 'value'], 200);
$response->json(['error' => 'Not found'], 404);

Send Plain Content ​

php
$response->send(
    content: '<h1>Hello World</h1>',
    statusCode: 200,
    headers: ['X-Custom' => 'value'],
    contentType: 'text/html'
);

No Content Response ​

For responses that should have no body (like successful deletions):

php
public function destroy(Response $response): void
{
    // Delete the resource...
    $response->noContent();  // 204 No Content
}

Created Response ​

For newly created resources:

php
public function store(Response $response): void
{
    // Create the resource...
    $response->created(['id' => 1, 'name' => 'New Resource']);  // 201 Created
}

Redirects ​

Redirect users to another URL:

php
public function login(Response $response): void
{
    $response->redirect('/dashboard');
}

// With status code
$response->redirect('/dashboard', 302);  // Temporary redirect
$response->redirect('/new-url', 301);    // Permanent redirect

Security

Redirects are validated to prevent open redirect vulnerabilities. Only redirects to the same host or relative paths are allowed by default.

File Downloads ​

Send a file for download:

php
public function download(Response $response): void
{
    $response->download(
        filePath: '/path/to/report.pdf',
        fileName: 'monthly-report.pdf',
        headers: ['X-Custom-Header' => 'value']
    );
}

The file is streamed efficiently without loading it entirely into memory.

Streaming Responses ​

For large responses or real-time data, use streaming:

php
public function export(Response $response): void
{
    $response->stream(function (callable $write): void {
        $write("data: Starting export...\n\n");
        
        foreach ($this->getLargeDataset() as $row) {
            $write(json_encode($row) . "\n");
        }
        
        $write("data: Export complete\n\n");
    }, 200, [
        'Content-Type' => 'text/event-stream',
        'Cache-Control' => 'no-cache',
    ]);
}

JsonResponse Class ​

The JsonResponse class provides a fluent interface for building JSON responses:

php
use Lalaz\Web\Http\JsonResponse;

// Basic usage
return new JsonResponse(['users' => []], 200);

// Using static factory
return JsonResponse::create(['users' => []], 200);

// Success response
return JsonResponse::success(['user' => $user], 'Created successfully');

// Error response
return JsonResponse::error('Not found', 404);
return JsonResponse::error('Validation failed', 422, ['email' => 'Invalid']);

Fluent Methods ​

php
return JsonResponse::create(['user' => $user])
    ->status(201)
    ->header('X-Custom', 'value')
    ->with('meta', ['version' => '1.0'])
    ->pretty();  // Enable pretty printing

Adding Data ​

php
$response = JsonResponse::create(['user' => $user]);

// Add single value
$response->with('timestamp', time());

// Add multiple values
$response->with([
    'timestamp' => time(),
    'version' => '1.0',
]);

Common Response Patterns ​

Success with Data ​

php
public function show(Request $request): array
{
    $id = $request->routeParam('id');
    $user = $this->findUser($id);
    
    return ['user' => $user];
}

Created Resource ​

php
public function store(Request $request): mixed
{
    $data = $request->json();
    $user = $this->createUser($data);
    
    return json(['user' => $user], 201);
}

Validation Error ​

php
public function store(Request $request): mixed
{
    $errors = $this->validate($request->json());
    
    if (!empty($errors)) {
        return json_error('Validation failed', 422, $errors);
    }
    
    // Continue with creation...
}

Not Found ​

php
public function show(Request $request): mixed
{
    $id = $request->routeParam('id');
    $user = $this->findUser($id);
    
    if (!$user) {
        return json_error('User not found', 404);
    }
    
    return ['user' => $user];
}

No Content (Delete) ​

php
public function destroy(Request $request, Response $response): void
{
    $id = $request->routeParam('id');
    $this->deleteUser($id);
    
    $response->noContent();
}

HTTP Status Codes Reference ​

CodeConstantDescription
200OKSuccessful request
201CreatedResource created
204No ContentSuccess with no body
301Moved PermanentlyPermanent redirect
302FoundTemporary redirect
400Bad RequestInvalid request
401UnauthorizedAuthentication required
403ForbiddenAccess denied
404Not FoundResource not found
422Unprocessable EntityValidation error
500Internal Server ErrorServer error

Response Method Summary ​

MethodDescription
status($code)Set HTTP status code
header($name, $value)Add a response header
withHeaders($headers)Add multiple headers
json($data, $code)Send JSON response
send($content, $code, $headers, $type)Send plain content
noContent()Send 204 No Content
created($data)Send 201 Created with JSON
redirect($url, $code)Redirect to URL
download($path, $name, $headers)Send file download
stream($callback, $code, $headers)Send streaming response

Next Steps ​

Released under the MIT License.