Fundamentals
Response
Understanding the Response object in Lithia
The Response object in Lithia provides methods to send data back to the client, including JSON, HTML, files, and various HTTP status codes.
Basic Usage
src/routes/api/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
// Send JSON response
res.json({ message: 'Hello World' });
};src/routes/text/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
// Send text response using send()
res.send('Hello World');
};src/routes/html/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
// Send HTML response using send()
res
.setHeaders({
'Content-Type': 'text/html',
})
.send('<h1>Hello World</h1>');
};Response Methods
JSON Response
Send JSON data to the client
src/routes/users/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
const data = {
id: 1,
name: 'John Doe',
email: 'john@example.com'
};
res.json(data);
};Send Response
Send any data type with automatic content handling
src/routes/status/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
// Send string
res.send('Server is running');
// Send number
res.send(42);
// Send object (automatically becomes JSON)
res.send({ status: 'ok' });
};Redirect Response
Redirect the client to another URL
src/routes/redirect/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
// Permanent redirect (301)
res.redirect('/new-page', 301);
};src/routes/temp/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
// Temporary redirect (302)
res.redirect('/temporary-page');
};HTTP Status Code Helpers
Lithia provides convenient methods for common HTTP status codes
src/routes/success/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
// Success responses using helper methods
res.ok({ message: 'Success' }); // 200 OK
res.created({ id: 1, name: 'New Item' }); // 201 Created
res.noContent(); // 204 No Content
};src/routes/errors/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
// Client error responses using helper methods
res.badRequest({ error: 'Invalid input' }); // 400 Bad Request
res.unauthorized({ error: 'Authentication required' }); // 401 Unauthorized
res.forbidden({ error: 'Access denied' }); // 403 Forbidden
res.notFound({ error: 'Resource not found' }); // 404 Not Found
res.conflict({ error: 'Resource already exists' }); // 409 Conflict
res.unprocessableEntity({ error: 'Validation failed' }); // 422 Unprocessable Entity
res.tooManyRequests({ error: 'Rate limit exceeded' }); // 429 Too Many Requests
};src/routes/server-error/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
// Server error responses using helper methods
res.internalServerError({ error: 'Something went wrong' }); // 500 Internal Server Error
res.badGateway({ error: 'Upstream server error' }); // 502 Bad Gateway
res.serviceUnavailable({ error: 'Service temporarily unavailable' }); // 503 Service Unavailable
};Response Headers
Set custom response headers
src/routes/headers/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
// Set single header
res.addHeader('Content-Type', 'application/json');
res.addHeader('Cache-Control', 'no-cache');
// Set multiple headers
res.setHeaders({
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
'X-Custom-Header': 'custom-value'
});
res.json({ message: 'Response with custom headers' });
};Cookies
Set response cookies
src/routes/login/route.post.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
// Set a simple cookie
res.cookie('theme', 'dark');
// Set cookie with options
res.cookie('sessionId', 'abc123', {
httpOnly: true,
secure: true,
maxAge: 3600000, // 1 hour
sameSite: 'strict'
});
res.json({ message: 'Cookie set' });
};Error Handling
Handle errors with appropriate responses
src/routes/api/data/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
import { ValidationError, NotFoundError } from '@/errors';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
try {
const data = await processData();
res.json(data);
} catch (error) {
if (error instanceof ValidationError) {
res.status(400).json({
error: 'Validation failed',
details: error.message
});
}
if (error instanceof NotFoundError) {
res.status(404).json({
error: 'Resource not found'
});
}
// Generic error
res.status(500).json({
error: 'Internal server error'
});
}
};Response Templates
Use response templates for consistent formatting
utils/response.ts
import type { LithiaResponse } from 'lithia';
export function successResponse(data: any, message?: string) {
return {
success: true,
data,
message: message || 'Operation successful'
};
}
export function errorResponse(error: string, statusCode = 400) {
return {
success: false,
error,
statusCode
};
}src/routes/api/users/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
import { successResponse, errorResponse } from '@/utils/response';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
try {
const data = await getData();
res.json(successResponse(data));
} catch (error) {
res.status(500).json(errorResponse('Failed to get data', 500));
}
};CORS Helpers
Handle Cross-Origin Resource Sharing with built-in helpers.
Setting up CORS through the res object will override the CORS settings in the lithia.config.ts file.
src/routes/api/cors/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (req: LithiaRequest, res: LithiaResponse) => {
// Set CORS headers with helper method
res.cors({
origin: '*',
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
headers: ['Content-Type', 'Authorization'],
credentials: false
});
// Handle preflight requests
if (req.method === 'OPTIONS') {
res.status(200).end();
return;
}
res.json({ message: 'CORS enabled' });
};src/routes/api/secure/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (req: LithiaRequest, res: LithiaResponse) => {
// Restrictive CORS for specific origins
res.cors({
origin: ['https://myapp.com', 'https://www.myapp.com'],
methods: ['GET', 'POST'],
headers: ['Content-Type'],
credentials: true
});
res.json({ message: 'Secure CORS' });
};Cache Helpers
Set cache headers with built-in helpers
src/routes/api/cache/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
// Set cache headers with helper method
res.cache({
maxAge: 3600, // 1 hour
private: true,
mustRevalidate: true,
etag: 'abc123'
});
res.json({ message: 'Cached response' });
};src/routes/api/no-cache/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
// Disable caching
res.cache({
noCache: true,
noStore: true
});
res.json({ message: 'No cache response' });
};File Helpers
Send files with built-in helpers
src/routes/download/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
// Send file as download
res.download('./public/document.pdf', 'my-document.pdf', {
root: './',
headers: {
'Content-Type': 'application/pdf'
}
});
};src/routes/image/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (_req: LithiaRequest, res: LithiaResponse) => {
// Send file with appropriate headers
res.sendFile('./public/image.jpg', {
root: './',
cache: true,
headers: {
'Content-Type': 'image/jpeg'
}
});
};