ApnaPHP

Documentation

Response Object

ApnaPHP's Response object provides a comprehensive interface for creating and sending HTTP responses. It supports various content types, status codes, headers, and response formats.

1. Creating Responses

JSON Response

use ApnaPHP\Routing\Response;

// Basic JSON response
return Response::json(['message' => 'Success', 'data' => $user]);

// JSON response with custom status code
return Response::json(['error' => 'Not found'], 404);

// JSON response with headers
return Response::json($data, 200, ['X-Custom-Header' => 'value']);

HTML Response

// Basic HTML response
return Response::html('<h1>Hello World</h1>');

// HTML response with custom status code
return Response::html('<h1>Error</h1>', 500);

// HTML response with headers
return Response::html($content, 200, ['Content-Type' => 'text/html; charset=UTF-8']);

Text Response

// Plain text response
return Response::text('Hello World');

// Text response with custom status code
return Response::text('Error occurred', 500);

Redirect Response

// Basic redirect
return Response::redirect('/dashboard');

// Redirect with custom status code
return Response::redirect('/login', 301);

// Redirect with headers
return Response::redirect('/dashboard', 302, ['X-Redirect-From' => '/old-page']);

2. Response Properties

Status Code

$response = Response::json(['message' => 'Success']);
$response = $response->status(201); // Set status code to 201

// Get status code
$statusCode = $response->getStatus();

Headers

$response = Response::json(['message' => 'Success']);

// Set single header
$response = $response->header('X-Custom-Header', 'value');

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

// Get headers
$headers = $response->getHeaders();
$customHeader = $response->getHeader('X-Custom-Header');

Content

$response = Response::json(['message' => 'Success']);

// Set content
$response = $response->content('{"message": "Updated"}');

// Get content
$content = $response->getContent();

3. Response Methods

withStatus()

$response = Response::json(['message' => 'Success'])
    ->withStatus(201);

withHeader()

$response = Response::json(['message' => 'Success'])
    ->withHeader('X-Custom-Header', 'value');

withHeaders()

$response = Response::json(['message' => 'Success'])
    ->withHeaders([
        'X-Custom-Header' => 'value',
        'X-Another-Header' => 'another-value'
    ]);

withoutHeader()

$response = Response::json(['message' => 'Success'])
    ->withoutHeader('X-Custom-Header');

4. Common Response Patterns

Success Response

function POST(Request $request): Response
{
    try {
        $user = User::create($request->all());
        
        return Response::json([
            'success' => true,
            'message' => 'User created successfully',
            'data' => $user
        ], 201);
        
    } catch (Exception $e) {
        return Response::json([
            'success' => false,
            'message' => 'Failed to create user',
            'error' => $e->getMessage()
        ], 500);
    }
}

Error Response

function GET(Request $request): Response
{
    $user = User::find($request->param('id'));
    
    if (!$user) {
        return Response::json([
            'success' => false,
            'message' => 'User not found',
            'error' => 'USER_NOT_FOUND'
        ], 404);
    }
    
    return Response::json([
        'success' => true,
        'data' => $user
    ]);
}

Validation Error Response

function POST(Request $request): Response
{
    try {
        $validated = validate($request->all(), [
            'name' => 'required|min:3',
            'email' => 'required|email'
        ]);
        
        // Process validated data
        
    } catch (ValidationException $e) {
        return Response::json([
            'success' => false,
            'message' => 'Validation failed',
            'errors' => $e->errors()
        ], 422);
    }
}

5. File Responses

File Download

function GET(Request $request): Response
{
    $filePath = 'storage/uploads/document.pdf';
    
    if (!file_exists($filePath)) {
        return Response::json(['error' => 'File not found'], 404);
    }
    
    return Response::download($filePath, 'document.pdf');
}

File Serving (Inline)

function GET(Request $request): Response
{
    $filePath = 'storage/uploads/image.jpg';
    
    if (!file_exists($filePath)) {
        return Response::json(['error' => 'File not found'], 404);
    }
    
    return Response::file($filePath);
}

File with Custom Headers

function GET(Request $request): Response
{
    $filePath = 'storage/uploads/document.pdf';
    
    return Response::download($filePath, 'document.pdf', [
        'Content-Type' => 'application/pdf',
        'Content-Disposition' => 'attachment; filename="document.pdf"',
        'Cache-Control' => 'no-cache'
    ]);
}

6. Streaming Responses

Large Data Streaming

function GET(Request $request): Response
{
    $response = Response::text('');
    
    // Set headers for streaming
    $response = $response->withHeaders([
        'Content-Type' => 'application/json',
        'Transfer-Encoding' => 'chunked'
    ]);
    
    // Start output buffering
    ob_start();
    
    echo '[';
    $first = true;
    
    foreach (User::all() as $user) {
        if (!$first) {
            echo ',';
        }
        echo json_encode($user);
        $first = false;
        
        // Flush output
        if (ob_get_level()) {
            ob_flush();
        }
        flush();
    }
    
    echo ']';
    
    $content = ob_get_clean();
    return $response->content($content);
}

7. CORS Responses

CORS Headers

function OPTIONS(Request $request): Response
{
    return Response::json([])
        ->withHeaders([
            'Access-Control-Allow-Origin' => '*',
            'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, OPTIONS',
            'Access-Control-Allow-Headers' => 'Content-Type, Authorization',
            'Access-Control-Max-Age' => '3600'
        ]);
}

CORS for All Responses

function GET(Request $request): Response
{
    $response = Response::json(['data' => $data]);
    
    return $response->withHeaders([
        'Access-Control-Allow-Origin' => '*',
        'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE',
        'Access-Control-Allow-Headers' => 'Content-Type, Authorization'
    ]);
}

8. Cache Responses

Cache Headers

function GET(Request $request): Response
{
    $data = getExpensiveData();
    
    return Response::json($data)
        ->withHeaders([
            'Cache-Control' => 'public, max-age=3600',
            'ETag' => md5(json_encode($data)),
            'Last-Modified' => gmdate('D, d M Y H:i:s', time()) . ' GMT'
        ]);
}

Conditional Requests

function GET(Request $request): Response
{
    $data = getData();
    $etag = md5(json_encode($data));
    
    // Check if client has cached version
    if ($request->header('If-None-Match') === $etag) {
        return Response::text('')
            ->withStatus(304)
            ->withHeader('ETag', $etag);
    }
    
    return Response::json($data)
        ->withHeaders([
            'ETag' => $etag,
            'Cache-Control' => 'public, max-age=3600'
        ]);
}

9. Response Middleware

Response Transformation

function GET(Request $request): Response
{
    $data = getData();
    
    // Transform data
    $transformedData = [
        'success' => true,
        'data' => $data,
        'meta' => [
            'timestamp' => time(),
            'version' => '1.0.0'
        ]
    ];
    
    return Response::json($transformedData);
}

Response Logging

function POST(Request $request): Response
{
    $response = processRequest($request);
    
    // Log response
    console_info('API Response', [
        'status' => $response->getStatus(),
        'headers' => $response->getHeaders(),
        'content_length' => strlen($response->getContent())
    ]);
    
    return $response;
}

10. Error Responses

Standard Error Responses

// 400 Bad Request
return Response::json(['error' => 'Bad Request'], 400);

// 401 Unauthorized
return Response::json(['error' => 'Unauthorized'], 401);

// 403 Forbidden
return Response::json(['error' => 'Forbidden'], 403);

// 404 Not Found
return Response::json(['error' => 'Not Found'], 404);

// 405 Method Not Allowed
return Response::json(['error' => 'Method Not Allowed'], 405);

// 422 Unprocessable Entity
return Response::json(['error' => 'Validation Failed'], 422);

// 429 Too Many Requests
return Response::json(['error' => 'Too Many Requests'], 429);

// 500 Internal Server Error
return Response::json(['error' => 'Internal Server Error'], 500);

Custom Error Response

function GET(Request $request): Response
{
    try {
        $data = getData();
        return Response::json($data);
        
    } catch (DatabaseException $e) {
        return Response::json([
            'error' => 'Database Error',
            'message' => 'Unable to retrieve data',
            'code' => 'DB_ERROR'
        ], 500);
        
    } catch (ValidationException $e) {
        return Response::json([
            'error' => 'Validation Error',
            'message' => 'Invalid input data',
            'details' => $e->errors()
        ], 422);
        
    } catch (Exception $e) {
        return Response::json([
            'error' => 'Server Error',
            'message' => 'An unexpected error occurred'
        ], 500);
    }
}

11. Response Helpers

withSuccess()

function POST(Request $request): Response
{
    $user = User::create($request->all());
    
    return Response::json($user)
        ->withSuccess('User created successfully');
}

withError()

function POST(Request $request): Response
{
    try {
        $user = User::create($request->all());
        return Response::json($user);
        
    } catch (Exception $e) {
        return Response::json([])
            ->withError('Failed to create user: ' . $e->getMessage());
    }
}

withMessage()

function GET(Request $request): Response
{
    $data = getData();
    
    return Response::json($data)
        ->withMessage('Data retrieved successfully');
}

12. Response Validation

Response Size Check

function GET(Request $request): Response
{
    $data = getLargeData();
    $response = Response::json($data);
    
    // Check response size
    $contentLength = strlen($response->getContent());
    if ($contentLength > 1024 * 1024) { // 1MB limit
        return Response::json([
            'error' => 'Response too large',
            'message' => 'Please use pagination or filters'
        ], 413);
    }
    
    return $response;
}

13. Best Practices

  • Use Appropriate Status Codes: Use correct HTTP status codes for different scenarios.
  • Consistent Response Format: Maintain consistent response format across your API.
  • Error Handling: Always handle errors gracefully and provide meaningful error messages.
  • Security Headers: Include security headers like CORS, CSP, etc.
  • Performance: Use caching headers to improve performance.
  • Content-Type: Always set appropriate Content-Type headers.
  • Response Size: Be mindful of response size and implement pagination for large datasets.

The Response object provides a powerful and flexible interface for creating HTTP responses in ApnaPHP applications.