Overriding the Express API覆盖Express API

The Express API consists of various methods and properties on the request and response objects. These are inherited by prototype. There are two extension points for the Express API:Express API由请求和响应对象上的各种方法和属性组成。这些是原型继承的。Express API有两个扩展点:

  1. The global prototypes at express.request and express.response.express.requestexpress.response的全球原型。
  2. App-specific prototypes at app.request and app.response.应用程序特定的原型在app.requestapp.response时。

Altering the global prototypes will affect all loaded Express apps in the same process. If desired, alterations can be made app-specific by only altering the app-specific prototypes after creating a new app.更改全局原型将影响同一过程中加载的所有Express应用程序。如果需要,可以通过在创建新应用程序后仅更改特定于应用程序的原型来进行特定于应用的更改。

Methods方法

You can override the signature and behavior of existing methods with your own, by assigning a custom function.通过分配自定义函数,您可以用自己的方法覆盖现有方法的签名和行为。

Following is an example of overriding the behavior of res.sendStatus.以下是覆盖res.sendStatus行为的示例。

app.response.sendStatus = function (statusCode, type, message) {
  // code is intentionally kept simple for demonstration purpose
  return this.contentType(type)
    .status(statusCode)
    .send(message)
}

The above implementation completely changes the original signature of res.sendStatus. It now accepts a status code, encoding type, and the message to be sent to the client.上述实现完全改变了res.sendStatus的原始签名。它现在接受状态代码、编码类型和要发送到客户端的消息。

The overridden method may now be used this way:现在可以这样使用重写的方法:

res.sendStatus(404, 'application/json', '{"error":"resource not found"}')

Properties属性

Properties in the Express API are either:Express API中的属性为:

  1. Assigned properties (ex: req.baseUrl, req.originalUrl)分配的属性(例如:req.baseUrlreq.originalUrl
  2. Defined as getters (ex: req.secure, req.ip)定义为getter(例如:req.securereq.ip

Since properties under category 1 are dynamically assigned on the request and response objects in the context of the current request-response cycle, their behavior cannot be overridden.由于类别1下的属性是在当前请求-响应周期的上下文中动态分配给requestresponse对象的,因此它们的行为不能被覆盖。

Properties under category 2 can be overwritten using the Express API extensions API.类别2下的属性可以使用Express API扩展API覆盖。

The following code rewrites how the value of req.ip is to be derived. Now, it simply returns the value of the Client-IP request header.以下代码重写了如何导出req.ip的值。现在,它只返回Client-IP请求头的值。

Object.defineProperty(app.request, 'ip', {
  configurable: true,
  enumerable: true,
  get () { return this.get('Client-IP') }
})

Prototype原型

In order to provide the Express API, the request/response objects passed to Express (via app(req, res), for example) need to inherit from the same prototype chain. 为了提供Express API,传递给Express的请求/响应对象(例如,通过app(req, res))需要从同一原型链继承。By default, this is http.IncomingRequest.prototype for the request and http.ServerResponse.prototype for the response.默认情况下,这是请求的http.IncomingRequest.prototype和响应的http.ServerResponse.prototype

Unless necessary, it is recommended that this be done only at the application level, rather than globally. Also, take care that the prototype that is being used matches the functionality as closely as possible to the default prototypes.除非有必要,否则建议仅在应用程序级别而不是全局级别执行此操作。此外,请注意,所使用的原型应尽可能与默认原型的功能相匹配。

// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse
// for the given app reference
Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype)
Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype)