It’s useful to be able to provide a unified response “envelope” when creating a REST API. This envelope can contain metadata, data and information on errors and warnings.
To do so with express for nodejs you can add custom functions to the request prototype and declare them in a module augmentation.
import { Response } from "express-serve-static-core";
import { response } from "express";
// augment the `express-serve-static-core` module
declare module "express-serve-static-core" {
// first, declare that we are adding a method to `Response` (the interface)
export interface Response {
respondWithData(data: any): this;
}
}
// now actually add it to `response` (the prototype)
response.respondWithData = function(data) {
return this.json({ errors: null, data: data });
};
Possibly confusing:
The value
requestimported from express refers is the prototype of request objects passed to handler functions; it implements theRequestinterface exported by express-serve-static-coreThe interface
Requestimported from express-serve-static-core refers to a Typescript interface and has no runtime meaning
After we’ve declared the method and added it to the prototype, we can now call it from our route handler:
app.get("/foo", async(req, res) => {
res.respondWithData({ success: true });
});