Once your API Route has processed a request, it needs to send a response back to the client. Next.js provides a convenient way to do this using the res object, which is an instance of the Node.js http.ServerResponse object. This object allows you to control the content, status code, and headers of your API's response.
The most common way to send data back from an API is in JSON format. This is ideal for structured data that your frontend application can easily parse and use. You can achieve this by using the res.json() method. This method automatically stringifies your JavaScript object to JSON and sets the Content-Type header to application/json.
export default function handler(req, res) {
const data = {
message: 'Hello from your API!',
timestamp: new Date().toISOString()
};
res.status(200).json(data);
}Sometimes, you might want to send plain text as a response, perhaps for a simple health check endpoint or a basic message. You can use the res.send() method for this. When used with a string, it sends that string as the response body and sets the Content-Type header to text/html by default. You can also explicitly set the content type if needed.
export default function handler(req, res) {
res.setHeader('Content-Type', 'text/plain');
res.status(200).send('API is operational.');
}Controlling the HTTP status code is crucial for indicating the outcome of an API request. Common status codes include: 200 (OK), 201 (Created), 400 (Bad Request), 401 (Unauthorized), 404 (Not Found), and 500 (Internal Server Error). You can set the status code using the res.status() method before sending the response.
export default function handler(req, res) {
const userId = req.query.id;
if (!userId) {
return res.status(400).json({ error: 'User ID is required.' });
}
// Simulate fetching user data
const user = { id: userId, name: 'Jane Doe' };
if (user) {
res.status(200).json(user);
} else {
res.status(404).json({ error: 'User not found.' });
}
}It's important to ensure that you only send one response per API route handler. If you call res.send(), res.json(), or res.end() multiple times within the same handler, it will lead to an error. Always use return after sending a response to prevent further execution of the handler.
// Incorrect example - will cause an error
export default function handler(req, res) {
res.status(200).json({ message: 'First response' });
res.status(200).json({ message: 'Second response' }); // This will fail
}// Correct example
export default function handler(req, res) {
const data = { message: 'Successful response' };
res.status(200).json(data);
return; // Or return res.status(200).json(data);
}You can also set custom headers on your response using res.setHeader(). This is useful for controlling caching, setting content types explicitly, or providing additional metadata.
export default function handler(req, res) {
res.setHeader('X-Custom-Header', 'My API Value');
res.status(200).json({ message: 'Response with custom header' });
}graph TD
A[Client Request] --> B(API Route Handler);
B -- Process Request --> C{Determine Response Type & Status};
C -- JSON Data --> D[res.json()];
C -- Plain Text --> E[res.send()];
C -- Set Status Code --> F[res.status()];
D --> G[HTTP Response];
E --> G;
F --> G;
G --> A;