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.
