node-res v5.0.1
Node res is a facade to be used by any framework to send HTTP response from a given request. The res object of Node.js is very low level and not enjoyable to work with.
Table of contents
- Features
- Getting started
- Explicit Mode
- Typescript support
- Extending via Macros
- Difference from other frameworks
- API
Features
- Support for JSON, JSONP response types.
- Automatically generates etag to enable caching.
- Serializes response body and set appropriate headers for it.
- Elegantly closes readable stream when piping a stream to the response.
- Files download.
- Helper methods.
- Typings support
- Extendable from outside
- Thoroughly tested.
Getting started
Install the package from npm as follows:
npm i node-res
# yarn
yarn add node-res
and then use it by importing it as follows:
const { Response } = require('node-res')
const http = require('http')
const options = {
etag: true,
jsonpCallbackName: 'callback'
}
http.createServer(function (req, res) {
const response = new Response(req, res, options)
response.status(201).json({ ok: true })
})
Raw Node.js API
http.createServer(function (req, res) {
const body = JSON.stringify({ ok: true })
res.statusCode = 201
res.setHeader('content-type', 'application/json')
res.setHeader('content-length', Buffer.byteLength(body))
res.write(body)
res.end()
})
As you can see, sending JSON response from the raw res
object requires little bit of extra work and the purpose of this module is to abstract those low level API's to a consistent set of high level API's.
Explicit Mode
This mode is used by AdonisJs Framework
The response/res
object in Node.js and in many popular frameworks like Express, Fastify will write the response body as soon as you will call res.send
method.
This is okay, if your HTTP request stack is simple and doesn't have many abstraction layers. However, if you heavily make use of middleware and want to modify the response body inside a middleware, it's impossible to do that.
Whereas, this module comes with a switch (explicitEnd)
, using that you can tell it to not write the response unless response.finish
is called explicitly.
http.createServer(function (req, res) {
const response = new Response(req, res, {})
response.explicitEnd = true
// response is saved in memory
response.send({ ok: true })
response.hasLazyBody // true
response.lazyBody // { writer, args: [] }
// now writing
response.finish()
})
This is how explicitEnd=true
works in nutshell
- Any calls to methods
send
,json
,jsonp
will be buffered and stored inside memory. - No headers will be set.
- Consecutive calls to previous methods will override the existing memory reference with the new one.
- The response is only written to the TCP socket when
response.finish
is called. - Consecutive calls to
response.finish
results in anoop
.
Typescript support
The module is written in Typescript, so expect intellisense to work out of the box. Also an interface is exported, which you can extend if extending the original Response
class.
import { IResponse: BaseIResponse } from 'node-res/build/src/IResponse'
export interface IResponse extends BaseIResponse {
myCustomMethod (): string
}
and then use it as follows
import { IResponse } from './my/interfaces'
http.createServer(function (req, res) {
const response: IResponse = new Response(req, res, {})
response.myCustomMethod() // intellisense works
})
Extending via Macros
The module extends macroable, which allows extending classes from outside in. You can use the following methods to extend the prototype of the Response
class.
import { Response } from 'node-res'
// Added as a method
Response.macro('status', function () {
return this.response.statusCode
})
// Added as property
Response.getter('status', function () {
return this.response.statusCode
})
// Added as singleton property
Response.getter('status', function () {
return this.response.statusCode
}, true)
Later, using the request instance, you can use getters
and macros
.
http.createServer(function (req, res) {
const response = new Response(req, res, {})
response.status // getter
response.status() // macro
})
Difference from other frameworks
You don't need this module, if you are using Express or Koa, since their res
object is already decorated with handful of convenient getters.
In case you are building a framework or using a framework like micro, then this module can save lots of time.
API
The API docs are generated using TypeDoc and can be found here.
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago