Skip to Content
πŸŽ‰ Welcome to my notes πŸŽ‰
Express.jsMastering the API Response πŸ“€

Mastering the API Response πŸ“€

Crafting a good API response is more than just sending data. A high-quality response includes a clear status code indicating the outcome, appropriate headers providing context, and a well-formatted body containing the data. The Express response (res) object provides a rich set of helper methods to make this process simple and expressive.

Sending Data: res.json() vs. res.send()

While both methods can send data, res.json() is the standard choice for building REST APIs.

  • res.json([body]): This method is specifically designed to send a JSON response. It automatically:
    1. Serializes a JavaScript object or array into a JSON string.
    2. Sets the Content-Type header to application/json.
  • res.send([body]): This is a more versatile, general-purpose method. It can send strings, objects, arrays, or Buffers. It intelligently tries to set the Content-Type header based on the data, but for APIs, res.json() is more explicit and conventional.

Best Practice: When building an API, always use res.json() to ensure your responses are consistent.

index.js
app.get("/api/user", (req, res) => { const user = { id: 1, name: "Alice", role: "admin" }; // This is the standard way to send JSON data. res.json(user); });

Setting the Status: res.status() and res.sendStatus()

Using the correct HTTP status code is crucial for a well-behaved API.

  • res.status(code): This method sets the HTTP status code. It is chainable, meaning you can call another response method right after it. This is the most common way to set a status.
  • res.sendStatus(code): This method sets the status code AND sends the default text representation as the response body (e.g., 404 sends β€œNot Found”). It ends the response cycle immediately.

Common Status Codes:

  • 200: OK
  • 201: Created (after a successful POST)
  • 400: Bad Request (e.g., invalid user input)
  • 404: Not Found
  • 500: Internal Server Error
index.js
app.get("/api/items/:id", (req, res) => { const item = findItemById(req.params.id); // A fictional function if (item) { // Chain .status() with .json() for a successful response res.status(200).json(item); } else { // Chain .status() with .json() for an error response res.status(404).json({ error: "Item not found" }); } });

Setting Headers: res.set()

The res.set() (or res.header()) method allows you to set custom HTTP response headers.

index.js
app.get("/api/data", (req, res) => { res.set("X-Request-ID", "some-unique-id-123"); res.set("Cache-Control", "no-store"); // Tell the browser not to cache this res.status(200).json({ data: "This is some sensitive data" }); });

Prompting File Downloads: res.download()

This utility method is used to prompt the client to download a file. It automatically sets the necessary headers, like Content-Disposition, which tells the browser to open a β€œSave As…” dialog.

  • res.download(path, [filename], [callback]):
    • path: The path to the file on the server.
    • filename (optional): The name you want the file to have when downloaded.
    • callback (optional): A function to call after the transfer is complete or if an error occurs.
index.js
const path = require("path"); app.get("/download-report", (req, res) => { const filePath = path.join(__dirname, "reports", "report-2025.pdf"); // This will trigger a download prompt in the browser for 'report-2025.pdf' res.download(filePath, (err) => { if (err) { // Handle errors, like if the file doesn't exist res.status(404).send("Report not found."); } }); });

✨ Summary

  • Use res.json() as the standard for sending API data.
  • Always set the correct HTTP status code using the chainable res.status() method.
  • Use res.set() to add custom or standard headers to your response.
  • Use res.download() to easily trigger a file download on the client.
  • Remember that every route handler must end the request-response cycle by calling one of these response-sending methods.
Last updated on