Back to results for “HTML & Web Servers”
Node.js › HTTP & Web Servers

What is content negotiation in HTTP, and how would a Node.js API implement it to return either JSON or XML based on a client's Accept header?

Intermediate

Answer

Content negotiation lets a single endpoint serve different representations of the same underlying resource based on what the client indicates it prefers via the Accept request header -- an Express route can inspect req.accepts() (which parses and matches against the Accept header) to determine the client's preferred format and respond accordingly, returning a 406 Not Acceptable if none of the server's supported formats match what the client will accept.
app.get('/users/:id', (req, res) => {
  const user = getUserData(req.params.id);
  res.format({
    'application/json': () => res.json(user),
    'application/xml': () => res.send(convertToXml(user)),
    default: () => res.status(406).send('Not Acceptable'),
  });
});
Real-world example A legacy-system integration API supports both modern JSON-consuming clients and an older partner system that can only parse XML, using content negotiation on a single endpoint to serve the appropriate format to each based on their Accept header, rather than maintaining two entirely separate endpoints.

Common follow-ups: How common is content negotiation in modern API design compared to simply using separate versioned or suffixed endpoints (like /users.xml)?;What other HTTP headers besides Accept participate in content negotiation, like Accept-Language?