Request & Response Objects
Learn how to work with HTTP requests and responses in Kempo Server.
Request Object
Kempo Server provides a request object that makes working with HTTP requests easier:
Properties
request.params- Route parameters from dynamic routes (e.g.,{ id: "123", info: "info" })request.query- Query string parameters as an object (e.g.,{ page: "1", limit: "10" })request.body- Pre-parsed request body (see Body Parsing below)request.path- The pathname of the request URLrequest.method- HTTP method (GET, POST, etc.)request.headers- Request headers objectrequest.url- Full request URL
Methods
await request.json()- Parse cached body as JSONawait request.text()- Get cached body as textawait request.buffer()- Get cached body as Bufferrequest.get(headerName)- Get specific header valuerequest.is(type)- Check if content-type contains specified type
Body Parsing
request.body is eagerly parsed before your route handler runs. The parsing strategy depends on the Content-Type header:
| Content-Type | request.body value |
|---|---|
application/json | Parsed object via JSON.parse(). If parsing fails, null. |
application/x-www-form-urlencoded | Parsed object via URLSearchParams |
| No body (GET, HEAD, Content-Length: 0) | null |
| Any other Content-Type | Raw string |
The convenience methods request.json(), request.text(), and request.buffer() still exist and return promises for backward compatibility, but they resolve immediately from the cached body.
Response Object
Kempo Server also provides a response object that makes sending responses easier:
Methods
response.json(object)- Send JSON response with automatic content-typeresponse.send(data)- Send response (auto-detects content type)response.html(htmlString)- Send HTML responseresponse.text(textString)- Send plain text responseresponse.status(code)- Set status code (chainable)response.set(field, value)- Set header (chainable)response.type(contentType)- Set content type (chainable)response.redirect(url, statusCode)- Redirect to URLresponse.cookie(name, value, options)- Set cookieresponse.clearCookie(name, options)- Clear cookie
Request Examples
Accessing Route Parameters
// api/user/[id]/GET.js
export default async function(request, response) {
const { id } = request.params;
const { includeDetails } = request.query;
// Fetch user data from database
const userData = await getUserById(id);
if (!userData) {
return response.status(404).json({ error: 'User not found' });
}
response.json(userData);
}
Handling JSON Data
// api/user/[id]/POST.js
export default async function(request, response) {
const { id } = request.params;
const { name, email } = request.body;
// request.body is already parsed from JSON
const updatedUser = await updateUser(id, { name, email });
response.json(updatedUser);
}
Working with Form Data
// contact/POST.js
// With Content-Type: application/x-www-form-urlencoded,
// request.body is automatically parsed into an object
export default async function(request, response) {
const { name, email, message } = request.body;
await sendContactEmail({ name, email, message });
response.html('<h1>Thank you for your message!</h1>');
}
Checking Headers
// api/upload/POST.js
export default async function(request, response) {
// Check if request contains JSON data
if (request.is('application/json')) {
const data = await request.json();
// Handle JSON data
}
// Check specific headers
const authHeader = request.get('authorization');
const userAgent = request.get('user-agent');
// Check request method
if (request.method === 'POST') {
// Handle POST request
}
response.json({ success: true });
}
Response Examples
Different Response Types
// Different response types
export default async function(request, response) {
// JSON response
response.json({ message: 'Hello World' });
// HTML response
response.html('<h1>Hello World</h1>');
// Text response
response.text('Hello World');
// Status code chaining
response.status(201).json({ created: true });
// Custom headers
response.set('X-Custom-Header', 'value').json({ data: 'test' });
// Redirect
response.redirect('/login');
// Set cookies
response.cookie('session', 'abc123', { httpOnly: true }).json({ success: true });
}
Error Handling
// api/user/[id]/DELETE.js
export default async function(request, response) {
const { id } = request.params;
try {
const user = await getUserById(id);
if (!user) {
return response.status(404).json({
error: 'User not found',
code: 'USER_NOT_FOUND'
});
}
await deleteUser(id);
response.status(200).json({
message: 'User deleted successfully',
deletedAt: new Date().toISOString()
});
} catch (error) {
response.status(500).json({
error: 'Internal server error',
code: 'INTERNAL_ERROR'
});
}
}
Content Negotiation
// api/user/[id]/GET.js
export default async function(request, response) {
const { id } = request.params;
const userData = await getUserById(id);
// Check Accept header to determine response format
const acceptHeader = request.get('accept');
if (acceptHeader && acceptHeader.includes('text/html')) {
// Return HTML representation
response.html(`
<div>
<h1>${userData.name}</h1>
<p>Email: ${userData.email}</p>
</div>
`);
} else {
// Default to JSON
response.json(userData);
}
}
Working with Cookies
// api/auth/login/POST.js
export default async function(request, response) {
const { username, password } = await request.json();
const user = await authenticateUser(username, password);
if (!user) {
return response.status(401).json({ error: 'Invalid credentials' });
}
// Set session cookie
const sessionToken = await createSessionToken(user.id);
response
.cookie('session', sessionToken, {
httpOnly: true,
secure: true,
sameSite: 'strict',
maxAge: 24 * 60 * 60 * 1000 // 24 hours
})
.json({
message: 'Login successful',
user: {
id: user.id,
username: user.username,
email: user.email
}
});
}
Advanced Request Handling
File Upload Handling
// api/upload/POST.js
export default async function(request, response) {
try {
// Get raw buffer for file upload
const buffer = await request.buffer();
const contentType = request.get('content-type');
// Save file to disk
const filename = `upload_${Date.now()}.${getExtensionFromMimeType(contentType)}`;
await fs.writeFile(`./uploads/${filename}`, buffer);
response.json({
message: 'File uploaded successfully',
filename: filename,
size: buffer.length
});
} catch (error) {
response.status(400).json({ error: 'Upload failed' });
}
}
Request Validation
// api/user/POST.js
export default async function(request, response) {
try {
const userData = await request.json();
// Validate required fields
const requiredFields = ['name', 'email', 'password'];
const missingFields = requiredFields.filter(field => !userData[field]);
if (missingFields.length > 0) {
return response.status(400).json({
error: 'Missing required fields',
missingFields
});
}
// Validate email format
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(userData.email)) {
return response.status(400).json({
error: 'Invalid email format'
});
}
// Create user
const newUser = await createUser(userData);
response.status(201).json({
message: 'User created successfully',
user: {
id: newUser.id,
name: newUser.name,
email: newUser.email
}
});
} catch (error) {
response.status(400).json({ error: 'Invalid request data' });
}
}