Request
Understanding the Request object in Lithia
The Request object in Lithia provides access to all incoming HTTP request data, including headers, query parameters, body, and more.
Basic Usage
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (req: LithiaRequest, res: LithiaResponse) => {
// Access request data
const method = req.method;
const url = req.url;
const headers = req.headers;
return res.json({ method, url, headers });
};Request Properties
Method
The HTTP method of the request (GET, POST, PUT, DELETE, etc.)
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (req: LithiaRequest, res: LithiaResponse) => {
if (req.method === 'GET') {
return res.json({ message: 'This is a GET request' });
}
if (req.method === 'POST') {
return res.json({ message: 'This is a POST request' });
}
return res.status(405).json({ error: 'Method not allowed' });
};URL and Path
Access the full URL and path segments
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (req: LithiaRequest, res: LithiaResponse) => {
const fullUrl = req.url(); // http://localhost:3000/users/123?name=john
const pathname = req.pathname; // /users/123
const query = req.query; // { name: 'john' }
return res.json({
fullUrl,
pathname,
query
});
};Headers
Access request headers
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (req: LithiaRequest, res: LithiaResponse) => {
const contentType = req.headers['content-type'];
const userAgent = req.userAgent();
const authorization = req.headers['authorization'];
return res.json({
contentType,
userAgent,
authorization
});
};Body
Access request body data
// POST /users - JSON data
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (req: LithiaRequest, res: LithiaResponse) => {
const body = await req.body<{ name: string; email: string }>();
const { name, email } = body;
return res.status(201).json({ name, email });
};// POST /form - Form data
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (req: LithiaRequest, res: LithiaResponse) => {
const formData = await req.body<Record<string, string>>();
return res.json({ received: formData });
};// POST /text - Plain text
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (req: LithiaRequest, res: LithiaResponse) => {
const text = await req.body<string>();
return res.json({ received: text });
};Path Parameters
Access dynamic route parameters
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (req: LithiaRequest, res: LithiaResponse) => {
const userId = req.params.id; // Access the [id] parameter
return res.json({ userId });
};Query Parameters
Access URL query parameters with automatic type conversion
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (req: LithiaRequest, res: LithiaResponse) => {
// Query parameters are automatically parsed and typed
const page = req.query.page || 1; // Automatically converted to number
const limit = req.query.limit || 10; // Automatically converted to number
const search = req.query.search; // String
const active = req.query.active; // Boolean (if 'true' or 'false')
const users = req.query.users; // Array of strings when ?users=1,2,3
return res.json({
page,
limit,
search,
active
});
};You can enable/disable this behavior on your lithia.config.ts file:
import { defineLithiaConfig } from 'lithia';
export default defineLithiaConfig({
server: {
request: {
queryParser: {
array: {
enabled: true,
delimiter: ',',
},
number: {
enabled: true,
},
boolean: {
enabled: true,
},
},
maxBodySize: 1048576,
},
},
});Cookies
Access request cookies
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (req: LithiaRequest, res: LithiaResponse) => {
const sessionId = req.cookie('sessionId');
const theme = req.cookie('theme') || 'light';
const allCookies = req.cookies();
return res.json({
sessionId,
theme,
allCookies
});
};Request Helpers
Lithia provides helpful methods to inspect request properties
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (req: LithiaRequest, res: LithiaResponse) => {
return res.json({
// Content type checks
isJson: req.isJson(),
isFormData: req.isFormData(),
isAjax: req.isAjax(),
// Network info
ip: req.ip(),
userAgent: req.userAgent(),
host: req.host(),
protocol: req.protocol(),
isSecure: req.isSecure(),
// Content acceptance
acceptsJson: req.accepts('application/json'),
acceptsHtml: req.accepts('text/html')
});
};import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (req: LithiaRequest, res: LithiaResponse) => {
// Different responses based on request type
if (req.isAjax()) {
return res.json({ message: 'AJAX request' });
}
if (req.accepts('text/html')) {
return res.html('<h1>HTML Response</h1>');
}
return res.json({ message: 'Default response' });
};Request Context Storage
Store and retrieve data during request processing
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (req: LithiaRequest, res: LithiaResponse) => {
// Store data in request context
req.set('userId', 123);
req.set('timestamp', Date.now());
// Retrieve data from request context
const userId = req.get<number>('userId');
const timestamp = req.get<number>('timestamp');
return res.json({ userId, timestamp });
};This context is available through the req object in all routes and middleware, including on hooks.
Request Validation
Validate incoming request data
import type { LithiaRequest, LithiaResponse } from 'lithia';
export default async (req: LithiaRequest, res: LithiaResponse) => {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
const body = await req.body();
if (!body.email || !body.password) {
return res.status(400).json({
error: 'Email and password are required'
});
}
// Process valid request
return res.json({ message: 'Login successful' });
};Middleware Integration
Use request data in middleware
import { UnauthorizedError, type LithiaMiddleware } from 'lithia';
import { getUserByToken } from '@/services/auth';
export function auth(): LithiaMiddleware {
return async (req, _res, next) => {
const token = req.headers.authorization;
if (!token) {
throw new UnauthorizedError(
'You are not authorized to access this resource',
);
}
const user = await getUserByToken(token);
if (!user) {
throw new UnauthorizedError(
'You are not authorized to access this resource',
);
}
req.set('user', user);
next();
};
}import type { LithiaRequest, LithiaResponse, LithiaMiddleware } from 'lithia';
import type { User } from '@/types/user';
import { auth } from '@/middlewares/auth';
export default async (req: LithiaRequest, res: LithiaResponse) => {
// User is available from middleware
const user = req.get<User>('user');
return res.json({ user });
};
export const middlewares: LithiaMiddleware[] = [auth()];Best Practices
- Always validate input data before processing
- Handle errors gracefully with proper status codes
- Sanitize user input to prevent security issues
- Use TypeScript for better type safety
import type { LithiaRequest, LithiaResponse } from 'lithia';
import { createUser } from '@/services/user';
import { z } from "zod";
const createUserSchema = z.object({
name: z.string(),
email: z.string(),
age: z.number(),
});
type CreateUserRequest = z.infer<typeof createUserSchema>;
export default async (req: LithiaRequest, res: LithiaResponse) => {
const body = await req.body<CreateUserRequest>();
const result = createUserSchema.safeParse(body);
if (!result.success) {
return res.status(400).json({
error: 'Invalid request body',
message: result.error.message,
});
}
const user = await createUser(result.data);
return res.status(201).json(user);
};