From f887623361257899f1fcd4fc84e599ca3292210a Mon Sep 17 00:00:00 2001 From: ArnaudBuchholz Date: Thu, 16 May 2024 10:29:52 -0400 Subject: [PATCH] documentation: iconfiguration --- docs/iconfiguration.md | 53 ++++++++++++++++++++++++++------------- reserve/@types/index.d.ts | 6 ++--- 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/docs/iconfiguration.md b/docs/iconfiguration.md index a59d86c7..751efff8 100644 --- a/docs/iconfiguration.md +++ b/docs/iconfiguration.md @@ -2,6 +2,19 @@ [🔝 REserve documentation](README.md) +```TypeScript +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 + dispatch: (request: IncomingMessage, response: ServerResponse) => Promise +} +``` + +> Types definitions for `IConfiguration` + ## Properties The configuration interface exposes **read-only** properties. @@ -14,13 +27,14 @@ Returns the dictionary of **handlers** indexed by their **prefix**. Returns the list of **mappings** *(array of objects)*. -Adding or removing mappings to the returned list, does **not** modify the current list : use [`setMappings`](#setMappings) for that purpose. +Adding or removing mappings to the returned list, does **not** modify the current list : use [`setMappings`](#methods) 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 : + * `'http'` * `'https'` @@ -28,23 +42,28 @@ Returns the current protocol being served : Returns a boolean indicating if the server implements [HTTP/2](https://en.wikipedia.org/wiki/HTTP/2). -## `async setMappings (mappings, request, timeout = 5000)` +## Methods + +### `async setMappings (mappings, request, timeout = 5000)` To **safely change** the list of mappings use the [asynchronous](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) `setMappings` method. -This API requires two parameters: +This API requires two parameters : + * the **new list** of mappings *(array of objects)* * the **current request** 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](https://github.com/ArnaudBuchholz/reserve/issues/39))* The API will: -* **validate** any new mapping *(relies on an internal detection mechanism based on symbols)* -* **wait** for all pending requests to be completed before applying the new mappings *(any new incoming request is put on hold in the meantime)*. The current request is not waited on. -**NOTE** : If the server implements [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/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`](https://github.com/ArnaudBuchholz/reserve/blob/master/doc/configuration.md). +* **validate** any new mapping *(relies on an internal detection mechanism based on symbols)*, +* **wait** for all pending requests to be completed before applying the new mappings *(any new incoming request is put on hold in the meantime)*.
The current request is **not** waited on *(because it is waiting on the `setMappings` call)*. + +> [!CAUTION] +> If the server implements [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/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`](configuration.md#exclude-from-holding-list). -## `async dispatch (request, response)` +### `async dispatch (request, response)` This API gives an **internal** access to the [dispatcher component](technical%20details.md#dispatcher). It takes a **request** and a **response**. Requests being processed through this API are flagged as `internal`. @@ -60,32 +79,30 @@ const { Request, Response } = require('reserve') * Instantiate the `Response` class to receive the dispatched response -This API should be use in specific use case, such as : - -* Implementing **batch requests** that are split into individual requests to be processed internally. - -For instance : +For instance, it can be used to implement **batch requests** that are split into individual requests to be processed internally. ```javascript -const { body, Request, Response } = require('reserve') +const { body, Request, Response, send } = require('reserve') module.exports = async function batchRequest (request, response) { - const requests = JSON.parse(await body(request)) + 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] + 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 => sendJSON(response, results)) + .then(results => send(response, results)) } ``` -* Implementing the [HTTP/2](https://en.wikipedia.org/wiki/HTTP/2) push mechanism : +> Example of batch request processing + +Another example is the implementation of [HTTP/2](https://en.wikipedia.org/wiki/HTTP/2) push mechanism. ```javascript function push (configuration, path, response) { @@ -99,3 +116,5 @@ function push (configuration, path, response) { }) } ``` + +> HTTP/2 push mechanism implementation diff --git a/reserve/@types/index.d.ts b/reserve/@types/index.d.ts index ca85db4d..30741a5c 100644 --- a/reserve/@types/index.d.ts +++ b/reserve/@types/index.d.ts @@ -225,12 +225,12 @@ declare module 'reserve' { } interface IConfiguration { - readonly handlers: Handlers - readonly mappings: Mapping[] + readonly handlers: { [key: string]: readonly Handler } + readonly mappings: (readonly Mapping)[] readonly http2: boolean readonly protocol: string setMappings: (mappings: Mapping[], request: IncomingMessage, timeout?: number) => Promise - dispatch: (request: IncomingMessage, response: ServerResponse) => void + dispatch: (request: IncomingMessage, response: ServerResponse) => Promise } function check (configuration: Configuration): Promise