Response
The response object is the primary way to send data back to the client. expressly provides methods to set the response status, headers, and body.
res.send()
The easiest way to deliver a response is to use the res.send() method. This method takes a single argument, which is the response body. The response body can be:
- A 
string, 
router.get('/', (req, res) => {
  res.send('Hello World!');
});
- A 
ReadableStream, 
router.get("/api", async (req, res) => {
  let originRequest = await fetch(
    "https://example.com", { backend: "my-origin" }
  );
  res.send(res.body);
});
- Or a 
Response: 
router.get("/origin", async (req, res) => {
  res.send(await fetch(
    "https://example.com", { backend: "my-origin" }
  ));
});
💡 If the experimental
autoContentTypeconfiguration option is enabled,res.sendwill try to infer theContent-Typeheader from the data it is passed, if the header is not set.
res.end()
Use to quickly end the response without any data. If you need to respond with data, instead use methods such as res.send() or res.json().
router.get('/', (req, res) => {
  res.end();
});
res.sendStatus()
Sets the response HTTP status code to statusCode and sends the registered status message as the text response body.
router.get('/', (req, res) => {
  res.sendStatus(403); // "Forbidden"
});
res.redirect()
When you want to redirect the user to another page, you can use the res.redirect() method. It will set a redirect status code and set the Location header to the URL you want to redirect to.
router.get('/', function(req, res) {
  res.redirect('/about');
});
💡 This method accepts a second, optional argument – the redirect status code (defaults to
302).
router.get("/redirect", async (req, res) => {
  res.redirect("https://fastly.com", 307);
});
res.json()
To return a serialized JSON response (Content-Type: application/json):
router.get('/', function(req, res) {
  res.json({
    message: 'Hello world!'
  });
});
res.text()
To return a plain-text response (Content-Type: text/plain):
router.get("/api", async (req, res) => {
  res.text("Hello world!");
});
res.html()
To return a HTML response (Content-Type: text/html[; charset=my-charset]):
router.get("/page", async (req, res) => {
  // Takes a second, optional argument specifying a charset:
  res.html("<html><body><h1>This is HTML!</h1></body></html>", "utf-8");
});
res.withStatus()
expressly provides a chainable method to set the status code of a response:
router.get("/page", async (req, res) => {
  res
    .withStatus(404)
    .html("<html><body><h1>Page not found</h1></body></html>");
});
res.on('finish', callback)
Provides a useful listener for tidying up any post-request actions (e.g., sending logs, metrics or traces).
Note: The
finishevent is emitted immediately before the final response headers and body are handed off to the Fastly Compute platform, to send back to the client.
router.use((_, res) => {
  res.on("finish", (finalResponse) => {
    console.log("Response sent!", finalResponse);
  });
});
Response headers
Read more about manipulating response (and request) headers with expressly.
Cookies
Read how to set and expire response cookies.
Cache segmentation
res.vary()
Appends a field to the Vary response header.
res.vary("x-feature-flags");
res.surrogateKeys
expressly exposes res.surrogateKeys, a Set object that allows you to manipulate the Surrogate-Key header.
res.surrogateKeys.add("seasonal");
res.surrogateKeys.add("vegan");
res.surrogateKeys.delete("low-carb");
// List all surrogate keys
for (const key of res.surrogateKeys) {
  console.log(key);
}