reserve

Configuration interface

šŸ” REserve documentation

interface IConfiguration {
  readonly handlers: { [key: string]: readonly Handler }
  readonly mappings: (readonly Mapping)[]
  readonly http2: boolean
  readonly protocol: string
  setMappings: (mappings: Mapping[], request: IncomingMessage, timeout?: number) => Promise<void>
  dispatch: (request: IncomingMessage, response: ServerResponse) => Promise<void>
}

Types definitions for IConfiguration

Properties

The configuration interface exposes read-only properties.

handlers

Returns the dictionary of handlers indexed by their prefix.

mappings

Returns the list of mappings (array of objects).

Adding or removing mappings to the returned list, does not modify the current list : use setMappings for that purpose.

However, it is still possible to modify the mappingsā€™ content. It is recommended to be extremely careful when manipulating them, since you might break the logic of the server.

protocol

Returns the current protocol being served :

http2

Returns a boolean indicating if the server implements HTTP/2.

Methods

async setMappings (mappings, request, timeout = 5000)

To safely change the list of mappings use the asynchronous setMappings method.

This API requires two parameters :

An optional third numeric parameter can be used to specify a timeout (in ms, default 5000) after which the API fails (usefull to detect blocking situations, see #39)

The API will:

[!CAUTION] If the server implements server-sent events or any blocking request, this could lead to an infinite waiting time. To ignore such requests, use the mapping setting exclude-from-holding-list.

async dispatch (request, response)

This API gives an internal access to the dispatcher component. It takes a request and a response. Requests being processed through this API are flagged as internal.

The parameters can be initialized using the internal mock helpers :

const { Request, Response } = require('reserve')

For instance, it can be used to implement batch requests that are split into individual requests to be processed internally.

const { body, Request, Response, send } = require('reserve')

module.exports = async function batchRequest (request, response) {
  const requests = await body(request).json()
  const promises = requests.map(url => {
    const batchRequest = new Request('GET', url)
    Object.keys(request.headers).forEach(header => {
      batchRequest.headers[header] = request.headers[header]
    })
    const batchResponse = new Response()
    return this.configuration.dispatch(batchRequest, batchResponse)
      .then(() => JSON.parse(batchResponse.toString()))
  })
  return Promise.all(promises)
    .then(results => send(response, results))
}

Example of batch request processing

Another example is the implementation of HTTP/2 push mechanism.

function push (configuration, path, response) {
  response.createPushResponse({
    ':method': 'GET',
    ':path': path
  }, (err, res) => {
    if (!err) {
      configuration.dispatch(new Request('GET', path), res)
    }
  })
}

HTTP/2 push mechanism implementation