The Simple, Secure Framework Developers Trust
## Server
The server object is the main application container. The server manages all incoming requests
along with all the facilities provided by the framework. Each server supports a single connection
(e.g. listen to port `80`).
### <a name="server()" /> `server([options])`
Creates a new server object where:
- `options` - (optional) a [server configuration object](#server.options).
```js
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ load: { sampleInterval: 1000 } });
```
### <a name="server.options" /> Server options
The server options control the behavior of the server object. Note that the options object is
deeply cloned (with the exception of [`listener`](#server.options.listener) which is shallowly
copied) and should not contain any values that are unsafe to perform deep copy on.
All options are optionals.
#### <a name="server.options.address" /> `server.options.address`
Default value: `'::'` if IPv6 is available, otherwise `'0.0.0.0'` (i.e. all available network interfaces).
Sets the hostname or IP address the server will listen on. If not configured, defaults to
[`host`](#server.options.host) if present, otherwise to all available network interfaces. Set to
`'127.0.0.1'`, `'::1'`, or `'localhost'` to restrict the server to only those coming from the same host.
#### <a name="server.options.app" /> `server.options.app`
Default value: `{}`.
Provides application-specific configuration which can later be accessed via
[`server.settings.app`](#server.settings). The framework does not interact with this object. It is
simply a reference made available anywhere a `server` reference is provided.
Note the difference between `server.settings.app` which is used to store static configuration
values and [`server.app`](#server.app) which is meant for storing run-time state.
#### <a name="server.options.autolisten" /> `server.options.autoListen`
Default value: `true`.
Used to disable the automatic initialization of the [`listener`](#server.options.listener). When
`false`, indicates that the [`listener`](#server.options.listener) will be started manually outside
the framework.
Cannot be set to `false` along with a [`port`](#server.options.port) value.
#### <a name="server.options.cache" /> `server.options.cache`
Default value: `{ provider: { constructor: require('@hapi/catbox-memory'), options: { partition: 'hapi-cache' } } }`.
Sets up server-side caching providers. Every server includes a default cache for storing
application state. By default, a simple memory-based cache is created which has limited capacity
and capabilities.
**hapi** uses [**catbox**](https://hapi.dev/family/catbox/api) for its cache implementation which
includes support for common storage solutions (e.g. Redis, MongoDB, Memcached, Riak, among others).
Caching is only utilized if [methods](#server.methods) and [plugins](#plugins) explicitly store
their state in the cache.
The server cache configuration only defines the storage container itself. The configuration can be
assigned one or more (array):
- a class or prototype function (usually obtained by calling `require()` on a **catbox** strategy
such as `require('@hapi/catbox-redis')`). A new **catbox** [client](https://hapi.dev/family/catbox/api#client)
will be created internally using this constructor.
- a configuration object with the following:
- `engine` - a **catbox** engine object instance.
- `name` - an identifier used later when provisioning or configuring caching for
[server methods](#server.methods) or [plugins](#plugins). Each cache name must be unique.
A single item may omit the `name` option which defines the default cache. If every cache
includes a `name`, a default memory cache is provisioned as well.
- `provider` - a class, a constructor function, or an object with the following:
- `constructor` - a class or a prototype function.
- `options` - (optional) a settings object passed as-is to the `constructor` with the following:
- `partition` - (optional) string used to isolate cached data. Defaults to `'hapi-cache'`.
- other constructor-specific options passed to the `constructor` on instantiation.
- `shared` - if `true`, allows multiple cache users to share the same segment (e.g.
multiple methods using the same cache storage container). Default to `false`.
- One (and only one) of `engine` or `provider` is required per configuration object.
#### <a name="server.options.compression" /> `server.options.compression`
Default value: `{ minBytes: 1024 }`.
Defines server handling of content encoding requests. If `false`, response content encoding is
disabled and no compression is performed by the server.
##### <a name="server.options.compression.minBytes" /> `server.options.compression.minBytes`
Default value: '1024'.
Sets the minimum response payload size in bytes that is required for content encoding compression.
If the payload size is under the limit, no compression is performed.
#### <a name="server.options.debug" /> `server.options.debug`
Default value: `{ request: ['implementation'] }`.
Determines which logged events are sent to the console. This should only be used for development
and does not affect which events are actually logged internally and recorded. Set to `false` to
disable all console logging, or to an object with:
- `log` - a string array of server log tags to be displayed via `console.error()` when
the events are logged via [`server.log()`](#server.log()) as well as
internally generated [server logs](#server-logs). Defaults to no output.
- `request` - a string array of request log tags to be displayed via `console.error()` when
the events are logged via [`request.log()`](#request.log()) as well as
internally generated [request logs](#request-logs). For example, to display all errors,
set the option to `['error']`. To turn off all console debug messages set it to `false`.
To display all request logs, set it to `'*'`.
Defaults to uncaught errors thrown in external code (these errors are handled
automatically and result in an Internal Server Error response) or runtime errors due to
developer error.
For example, to display all errors, set the `log` or `request` to `['error']`. To turn off all
output set the `log` or `request` to `false`. To display all server logs, set the `log` or
`request` to `'*'`. To disable all debug information, set `debug` to `false`.
#### <a name="server.options.host" /> `server.options.host`
Default value: the operating system hostname and if not available, to `'localhost'`.
The public hostname or IP address. Used to set [`server.info.host`](#server.info) and
[`server.info.uri`](#server.info) and as [`address`](#server.options.address) if none is provided.
#### <a name="server.options.info.remote" /> `server.options.info.remote`
Default value: `false`.
If `true`, the `request.info.remoteAddress` and `request.info.remotePort` are populated when the request is received which can consume more resource (but is ok if the information is needed, especially for aborted requests). When `false`, the fields are only populated upon demand (but will be `undefined` if accessed after the request is aborted).
#### <a name="server.options.listener" /> `server.options.listener`
Default value: none.
An optional node HTTP (or HTTPS) [`http.Server`](https://nodejs.org/api/http.html#http_class_http_server)
object (or an object with a compatible interface).
If the `listener` needs to be manually started, set [`autoListen`](#server.options.autolisten) to
`false`.
If the `listener` uses TLS, set [`tls`](#server.options.tls) to `true`.
#### <a name="server.options.load" /> `server.options.load`
Default value: `{ sampleInterval: 0, maxHeapUsedBytes: 0, maxRssBytes: 0, maxEventLoopDelay: 0, maxEventLoopUtilization: 0 }`.
Server excessive load handling limits where:
- `sampleInterval` - the frequency of sampling in milliseconds. When set to `0`, the other load options are ignored. Defaults to `0` (no sampling).
- `maxHeapUsedBytes` - maximum V8 heap size over which incoming requests are rejected with an HTTP Server Timeout (503) response. Defaults to `0` (no limit).
- `maxRssBytes` - maximum process RSS size over which incoming requests are rejected with an HTTP Server Timeout (503) response. Defaults to `0` (no limit).
- `maxEventLoopDelay` - maximum event loop delay duration in milliseconds over which incoming requests are rejected with an HTTP Server Timeout (503) response. Defaults to `0` (no limit).
- `maxEventLoopUtilization` - maximum event loop utilization value over which incoming requests are rejected with an HTTP Server Timeout (503) response. Defaults to `0` (no limit).
#### <a name="server.options.mime" /> `server.options.mime`
Default value: none.
Options passed to the [**mimos**](https://hapi.dev/family/mimos/api) module when generating the mime database used by the server (and accessed via [`server.mime`](#server.mime)):
- `override` - an object hash that is merged into the built in mime information specified [here](https://github.com/jshttp/mime-db). Each key value pair represents a single mime object. Each override value must contain:
- `key` - the lower-cased mime-type string (e.g. `'application/javascript'`).
- `value` - an object following the specifications outlined [here](https://github.com/jshttp/mime-db#data-structure). Additional values include:
- `type` - specify the `type` value of result objects, defaults to `key`.
- `predicate` - method with signature `function(mime)` when this mime type is found in the database, this function will execute to allows customizations.
```js
const options = {
mime: {
override: {
'node/module': {
source: 'iana',
compressible: true,
extensions: ['node', 'module', 'npm'],
type: 'node/module'
},
'application/javascript': {
source: 'iana',
charset: 'UTF-8',
compressible: true,
extensions: ['js', 'javascript'],
type: 'text/javascript'
},
'text/html': {
predicate: function(mime) {
if (someCondition) {
mime.foo = 'test';
}
else {
mime.foo = 'bar';
}
return mime;
}
}
}
}
};
```
#### <a name="server.options.operations" /> `server.options.operations`
Default value: `{ cleanStop: true }`.
Defines server handling of server operations:
- `cleanStop` - if `true`, the server keeps track of open connections and properly closes them
when the server is stopped. Under normal load, this should not interfere with server performance.
However, under severe load connection monitoring can consume additional resources and aggravate
the situation. If the server is never stopped, or if it is forced to stop without waiting for
open connection to close, setting this to `false` can save resources that are not being utilized
anyway. Defaults to `true`.
#### <a name="server.options.plugins" /> `server.options.plugins`
Default value: `{}`.
Plugin-specific configuration which can later be accessed via [`server.settings.plugins`](#server.settings).
`plugins` is an object where each key is a plugin name and the value is the configuration.
Note the difference between [`server.settings.plugins`](#server.settings) which is used to store
static configuration values and [`server.plugins`](#server.plugins) which is meant for storing
run-time state.
#### <a name="server.options.port" /> `server.options.port`
Default value: `0` (an ephemeral port).
The TCP port the server will listen to. Defaults the next available port when the server is started
(and assigned to [`server.info.port`](#server.info)).
If `port` is a string containing a '/' character, it is used as a UNIX domain socket path.
If it starts with '\\.\pipe', it is used as a Windows named pipe.
#### <a name="server.options.query" /> `server.options.query`
Default value: `{}`.
Defines server handling of the request path query component.
##### <a name="server.options.query.parser" /> `server.options.query.parser`
Default value: none.
Sets a query parameters parser method using the signature `function(query)` where:
- `query` - an object containing the incoming [`request.query`](#request.query) parameters.
- the method must return an object where each key is a parameter and matching value is the
parameter value. If the method throws, the error is used as the response or returned when
[`request.setUrl()`](#request.setUrl()) is called.
```js
const Qs = require('qs');
const options = {
query: {
parser: (query) => Qs.parse(query)
}
};
```
#### <a name="server.options.router" /> `server.options.router`
Default value: `{ isCaseSensitive: true, stripTrailingSlash: false }`.
Controls how incoming request URIs are matched against the routing table:
- `isCaseSensitive` - determines whether the paths '/example' and '/EXAMPLE' are considered
different resources. Defaults to `true`.
- `stripTrailingSlash` - removes trailing slashes on incoming paths. Defaults to `false`.
#### <a name="server.options.routes" /> `server.options.routes`
Default value: none.
A [route options](#route-options) object used as the default configuration for every route.
#### <a name="server.options.state" /> `server.options.state`
Default value:
```js
{
strictHeader: true,
ignoreErrors: false,
isSecure: true,
isHttpOnly: true,
isSameSite: 'Strict',
isPartitioned: false,
encoding: 'none'
}
```
Sets the default configuration for every state (cookie) set explicitly via
[`server.state()`](#server.state()) or implicitly (without definition) using the
[state configuration](#server.state()) object.
#### <a name="server.options.tls" /> `server.options.tls`
Default value: none.
Used to create an HTTPS connection. The `tls` object is passed unchanged to the node
HTTPS server as described in the [node HTTPS documentation](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener).
Set to `true` when passing a [`listener`](#server.options.listener) object that has been configured
to use TLS directly.
#### <a name="server.options.uri" /> `server.options.uri`
Default value: constructed from runtime server information.
The full public URI without the path (e.g. 'http://example.com:8080'). If present, used as the
server [`server.info.uri`](#server.info), otherwise constructed from the server settings.
### Server properties
#### <a name="server.app" /> `server.app`
Access: read / write.
Provides a safe place to store server-specific run-time application data without potential
conflicts with the framework internals. The data can be accessed whenever the server is
accessible. Initialized with an empty object.
```js
const server = Hapi.server();
server.app.key = 'value';
const handler = function (request, h) {
return request.server.app.key; // 'value'
};
```
#### <a name="server.auth.api" /> `server.auth.api`
Access: authentication strategy specific.
An object where each key is an authentication strategy name and the value is the exposed strategy
API. Available only when the authentication scheme exposes an API by returning an `api` key in the
object returned from its implementation function.
```js
const server = Hapi.server({ port: 80 });
const scheme = function (server, options) {
return {
api: {
settings: {
x: 5
}
},
authenticate: function (request, h) {
const authorization = request.headers.authorization;
if (!authorization) {
throw Boom.unauthorized(null, 'Custom');
}
return h.authenticated({ credentials: { user: 'john' } });
}
};
};
server.auth.scheme('custom', scheme);
server.auth.strategy('default', 'custom');
console.log(server.auth.api.default.settings.x); // 5
```
#### <a name="server.auth.settings.default" /> `server.auth.settings.default`
Access: read only.
Contains the default authentication configuration if a default strategy was set via
[`server.auth.default()`](#server.auth.default()).
#### <a name="server.decorations" /> `server.decorations`
Access: read only.
Provides access to the decorations already applied to various framework interfaces. The object must
not be modified directly, but only through [`server.decorate`](#server.decorate()).
Contains:
- `request` - decorations on the [request object](#request).
- `response` - decorations on the [response object](#response-object).
- `toolkit` - decorations on the [response toolkit](#response-toolkit).
- `server` - decorations on the [server](#server) object.
```js
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
const success = function () {
return this.response({ status: 'ok' });
};
server.decorate('toolkit', 'success', success);
console.log(server.decorations.toolkit); // ['success']
```
#### <a name="server.events" /> `server.events`
Access: **podium** public interface.
The server events emitter. Utilizes the [**podium**](https://hapi.dev/family/podium/api) with support
for event criteria validation, channels, and filters.
Use the following methods to interact with `server.events`:
- [`server.event(events)`](#server.event()) - register application events.
- [`server.events.emit(criteria, data)`](#server.events.emit()) - emit server events.
- [`server.events.on(criteria, listener, context)`](#server.events.on()) - subscribe to all events.
- [`server.events.once(criteria, listener, context)`](#server.events.once()) - subscribe to a single event.
Other methods include: `server.events.removeListener(name, listener)`,
`server.events.removeAllListeners(name)`, and `server.events.hasListeners(name)`.
##### <a name="server.events.log" /> `'log'` Event
The `'log'` event type emits internal server events generated by the framework as well as
application events logged with [`server.log()`](#server.log()).
The `'log'` event handler uses the function signature `function(event, tags)` where:
- `event` - an object with the following properties:
- `timestamp` - the event timestamp.
- `tags` - an array of tags identifying the event (e.g. `['error', 'http']`).
- `channel` - set to `'internal'` for internally generated events, otherwise `'app'` for events
generated by [`server.log()`](#server.log()).
- `data` - event-specific information. Available when event data was provided and is not an
error. Errors are passed via `error`.
- `error` - the error object related to the event if applicable. Cannot appear together with
`data`.
- `tags` - an object where each `event.tag` is a key and the value is `true`. Useful for quick
identification of events.
```js
server.events.on('log', (event, tags) => {
if (tags.error) {
console.log(`Server error: ${event.error ? event.error.message : 'unknown'}`);
}
});
```
The internally generated events are (identified by their `tags`):
- `load` - logs the current server load measurements when the server rejects a request due to
[high load](#server.options.load). The event data contains the process load metrics.
- `connection` `client` `error` - a `clientError` event was received from the HTTP or HTTPS
listener. The event data is the error object received.
##### <a name="server.events.cachePolicy" /> `'cachePolicy'` Event
The `'cachePolicy'` event type is emitted when a server [cache policy](https://hapi.dev/module/catbox/api#policy)
is created via [`server.cache()`](#server.cache()) or a [`server.method()`](#server.method()) with caching enabled is registered.
The `'cachePolicy'` event handler uses the function signature `function(cachePolicy, cache, segment)` where:
- `cachePolicy` - the catbox [cache policy](https://hapi.dev/module/catbox/api#policy).
- `cache` - the [cache provision](#server.options.cache) name used when the policy was created or `undefined` if the default cache was used.
- `segment` - the segment name used when the policy was created.
```js
server.events.on('cachePolicy', (cachePolicy, cache, segment) => {
console.log(`New cache policy created using cache: ${cache === undefined ? 'default' : cache} and segment: ${segment}`);
});
```
##### <a name="server.events.request" /> `'request'` Event
The `'request'` event type emits internal request events generated by the framework as well as
application events logged with [`request.log()`](#request.log()).
The `'request'` event handler uses the function signature `function(request, event, tags)` where:
- `request` - the [request object](#request).
- `event` - an object with the following properties:
- `timestamp` - the event timestamp.
- `tags` - an array of tags identifying the event (e.g. `['error', 'http']`).
- `channel` - one of
- `'app'` - events generated by [`request.log()`](#request.log()).
- `'error'` - emitted once per request if the response had a `500` status code.
- `'internal'` - internally generated events.
- `request` - the request [identifier](#request.info.id).
- `data` - event-specific information. Available when event data was provided and is not an
error. Errors are passed via `error`.
- `error` - the error object related to the event if applicable. Cannot appear together with
`data`.
- `tags` - an object where each `event.tag` is a key and the value is `true`. Useful for quick
identification of events.
```js
server.events.on('request', (request, event, tags) => {
if (tags.error) {
console.log(`Request ${event.request} error: ${event.error ? event.error.message : 'unknown'}`);
}
});
```
To listen to only one of the channels, use the event criteria object:
```js
server.events.on({ name: 'request', channels: 'error' }, (request, event, tags) => {
console.log(`Request ${event.request} failed`);
});
```
The internally generated events are (identified by their `tags`):
- `accept-encoding` `error` - a request received contains an invalid Accept-Encoding header.
- `auth` `unauthenticated` - no authentication scheme included with the request.
- `auth` `unauthenticated` `response` `{strategy}` - the authentication strategy listed returned a non-error response (e.g. a redirect to a login page).
- `auth` `unauthenticated` `error` `{strategy}` - the request failed to pass the listed authentication strategy (invalid credentials).
- `auth` `unauthenticated` `missing` `{strategy}` - the request failed to pass the listed authentication strategy (no credentials found).
- `auth` `unauthenticated` `try` `{strategy}` - the request failed to pass the listed authentication strategy in `'try'` mode and will continue.
- `auth` `scope` `error` - the request authenticated but failed to meet the scope requirements.
- `auth` `entity` `user` `error` - the request authenticated but included an application entity when a user entity was required.
- `auth` `entity` `app` `error` - the request authenticated but included a user entity when an application entity was required.
- `ext` `error` - an `onPostResponse` extension handler errored.
- `handler` `error` - the route handler returned an error. Includes the execution duration and the error message.
- `pre` `error` - a pre method was executed and returned an error. Includes the execution duration, assignment key, and error.
- `internal` `error` - an HTTP 500 error response was assigned to the request.
- `internal` `implementation` `error` - an incorrectly implemented [lifecycle method](#lifecycle-methods).
- `request` `error` `abort` - the request aborted.
- `request` `error` `close` - the request closed prematurely.
- `request` `error` - the request stream emitted an error. Includes the error.
- `request` `server` `timeout` `error` - the request took too long to process by the server. Includes the timeout configuration value and the duration.
- `state` `error` - the request included an invalid cookie or cookies. Includes the cookies and error details.
- `state` `response` `error` - the response included an invalid cookie which prevented generating a valid header. Includes the error.
- `payload` `error` - failed processing the request payload. Includes the error.
- `response` `error` - failed writing the response to the client. Includes the error.
- `response` `error` `close` - failed writing the response to the client due to prematurely closed connection.
- `response` `error` `aborted` - failed writing the response to the client due to prematurely aborted connection.
- `response` `error` `cleanup` - failed freeing response resources.
- `validation` `error` `{input}` - input (i.e. payload, query, params, headers) validation failed. Includes the error. Only emitted when `failAction` is set to `'log'`.
- `validation` `response` `error` - response validation failed. Includes the error message. Only emitted when `failAction` is set to `'log'`.
##### <a name="server.events.response" /> `'response'` Event
The `'response'` event type is emitted after the response is sent back to the client (or when the
client connection closed and no response sent, in which case [`request.response`](#request.response)
is `null`). A single event is emitted per request. The `'response'` event handler uses the function
signature `function(request)` where:
- `request` - the [request object](#request).
```js
server.events.on('response', (request) => {
console.log(`Response sent for request: ${request.info.id}`);
});
```
##### <a name="server.events.route" /> `'route'` Event
The `'route'` event type is emitted when a route is added via [`server.route()`](#server.route()).
The `'route'` event handler uses the function signature `function(route)` where:
- `route` - the [route information](#request.route). The `route` object must not be modified.
```js
server.events.on('route', (route) => {
console.log(`New route added: ${route.path}`);
});
```
##### <a name="server.events.start" /> `'start'` Event
The `'start'` event type is emitted when the server is started using [`server.start()`](#server.start()).
The `'start'` event handler uses the function signature `function()`.
```js
server.events.on('start', () => {
console.log('Server started');
});
```
##### <a name="server.events.closing" /> `'closing'` Event
The `'closing'` event type is emitted when the server is stopped using [`server.stop()`](#server.stop()). It is triggered when incoming requests are no longer accepted but before all underlying active connections have been closed, and thus before the [`'stop'`](#server.events.stop) event is triggered.
The `'closing'` event handler uses the function signature `function()`.
```js
server.events.on('closing', () => {
console.log('Server is closing');
});
```
##### <a name="server.events.stop" /> `'stop'` Event
The `'stop'` event type is emitted when the server is stopped using [`server.stop()`](#server.stop()).
The `'stop'` event handler uses the function signature `function()`.
```js
server.events.on('stop', () => {
console.log('Server stopped');
});
```
#### <a name="server.info" /> `server.info`
Access: read only.
An object containing information about the server where:
- `id` - a unique server identifier (using the format '{hostname}:{pid}:{now base36}').
- `created` - server creation timestamp.
- `started` - server start timestamp (`0` when stopped).
- `port` - the connection port based on the following rules:
- before the server has been started: the configured [`port`](#server.options.port) value.
- after the server has been started: the actual port assigned when no port is configured or was
set to `0`.
- `host` - The [`host`](#server.options.host) configuration value.
- `address` - the active IP address the connection was bound to after starting. Set to `undefined`
until the server has been started or when using a non TCP port (e.g. UNIX domain socket).
- `protocol` - the protocol used:
- `'http'` - HTTP.
- `'https'` - HTTPS.
- `'socket'` - UNIX domain socket or Windows named pipe.
- `uri` - a string representing the connection (e.g. 'http://example.com:8080' or
'socket:/unix/domain/socket/path'). Contains the [`uri`](#server.options.uri) value if set,
otherwise constructed from the available settings. If no [`port`](#server.options.port) is
configured or is set to `0`, the `uri` will not include a port component until the server is
started.
```js
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
console.log(server.info.port); // 80
```
#### <a name="server.listener" /> `server.listener`
Access: read only and listener public interface.
The node HTTP server object.
```js
const Hapi = require('@hapi/hapi');
const SocketIO = require('socket.io');
const server = Hapi.server({ port: 80 });
const io = SocketIO.listen(server.listener);
io.sockets.on('connection', (socket) => {
socket.emit({ msg: 'welcome' });
});
```
#### <a name="server.load" /> `server.load`
Access: read only.
An object containing the process load metrics (when [`load.sampleInterval`](#server.options.load)
is enabled):
- `eventLoopDelay` - event loop delay milliseconds.
- `eventLoopUtilization` - current event loop utilization value.
- `heapUsed` - V8 heap usage.
- `rss` - RSS memory usage.
```js
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ load: { sampleInterval: 1000 } });
console.log(server.load.rss);
```
#### <a name="server.methods" /> `server.methods`
Access: read only.
Server methods are functions registered with the server and used throughout the application as a
common utility. Their advantage is in the ability to configure them to use the built-in cache and
share across multiple request handlers without having to create a common module.
`sever.methods` is an object which provides access to the methods registered via
[server.method()](#server.method()) where each server method name is an object
property.
```js
const Hapi = require('@hapi/hapi');
const server = Hapi.server();
server.method('add', (a, b) => (a + b));
const result = server.methods.add(1, 2); // 3
```
#### <a name="server.mime" /> `server.mime`
Access: read only and **mimos** public interface.
Provides access to the server MIME database used for setting content-type information. The object
must not be modified directly but only through the [`mime`](#server.options.mime) server setting.
```js
const Hapi = require('@hapi/hapi');
const options = {
mime: {
override: {
'node/module': {
source: 'steve',
compressible: false,
extensions: ['node', 'module', 'npm'],
type: 'node/module'
}
}
}
};
const server = Hapi.server(options);
console.log(server.mime.path('code.js').type) // 'application/javascript'
console.log(server.mime.path('file.npm').type) // 'node/module'
```
#### <a name="server.plugins" /> `server.plugins`
Access: read / write.
An object containing the values exposed by each registered plugin where each key is a plugin name
and the values are the exposed properties by each plugin using
[`server.expose()`](#server.expose()). Plugins may set the value of the
`server.plugins[name]` object directly or via the `server.expose()` method.
```js
exports.plugin = {
name: 'example',
register: function (server, options) {
server.expose('key', 'value');
server.plugins.example.other = 'other';
console.log(server.plugins.example.key); // 'value'
console.log(server.plugins.example.other); // 'other'
}
};
```
#### <a name="server.realm" /> `server.realm`
Access: read only.
The realm object contains sandboxed server settings specific to each plugin or authentication
strategy. When registering a plugin or an authentication scheme, a `server` object reference is
provided with a new `server.realm` container specific to that registration. It allows each plugin
to maintain its own settings without leaking and affecting other plugins.
For example, a plugin can set a default file path for local resources without breaking other
plugins' configured paths. When calling [`server.bind()`](#server.bind()), the active realm's
`settings.bind` property is set which is then used by routes and extensions added at the same level
(server root or plugin).
The `server.realm` object contains:
- `modifiers` - when the server object is provided as an argument to the plugin `register()`
method, `modifiers` provides the registration preferences passed the
[`server.register()`](#server.register()) method and includes:
- `route` - routes preferences:
- `prefix` - the route path prefix used by any calls to [`server.route()`](#server.route())
from the server. Note that if a prefix is used and the route path is set to `'/'`, the
resulting path will not include the trailing slash.
- `vhost` - the route virtual host settings used by any calls to
[`server.route()`](#server.route()) from the server.
- `parent` - the realm of the parent server object, or `null` for the root server.
- `plugin` - the active plugin name (empty string if at the server root).
- `pluginOptions` - the plugin options passed at registration.
- `plugins` - plugin-specific state to be shared only among activities sharing the same active
state. `plugins` is an object where each key is a plugin name and the value is the plugin state.
- `settings` - settings overrides:
- `files.relativeTo`
- `bind`
The `server.realm` object should be considered read-only and must not be changed directly except
for the `plugins` property which can be directly manipulated by each plugin, setting its properties
inside `plugins[name]`.
```js
exports.register = function (server, options) {
console.log(server.realm.modifiers.route.prefix);
};
```
#### <a name="server.registrations" /> `server.registrations`
Access: read only.
An object of the currently registered plugins where each key is a registered plugin name and the
value is an object containing:
- `version` - the plugin version.
- `name` - the plugin name.
- `options` - (optional) options passed to the plugin during registration.
#### <a name="server.settings" /> `server.settings`
Access: read only.
The server configuration object after defaults applied.
```js
const Hapi = require('@hapi/hapi');
const server = Hapi.server({
app: {
key: 'value'
}
});
console.log(server.settings.app); // { key: 'value' }
```
#### <a name="server.states" /> `server.states`
Access: read only and **statehood** public interface.
The server cookies manager.
#### <a name="server.states.settings" /> `server.states.settings`
Access: read only.
The server cookies manager settings. The settings are based on the values configured in
[`server.options.state`](#server.options.state).
#### <a name="server.states.cookies" /> `server.states.cookies`
Access: read only.
An object containing the configuration of each cookie added via [`server.state()`](#server.state())
where each key is the cookie name and value is the configuration object.
#### <a name="server.states.names" /> `server.states.names`
Access: read only.
An array containing the names of all configured cookies.
#### <a name="server.type" /> `server.type`
Access: read only.
A string indicating the listener type where:
- `'socket'` - UNIX domain socket or Windows named pipe.
- `'tcp'` - an HTTP listener.
#### <a name="server.version" /> `server.version`
Access: read only.
The **hapi** module version number.
```js
const Hapi = require('@hapi/hapi');
const server = Hapi.server();
console.log(server.version); // '17.0.0'
```
### <a name="server.auth.default()" /> `server.auth.default(options)`
Sets a default strategy which is applied to every route where:
- `options` - one of:
- a string with the default strategy name
- an authentication configuration object using the same format as the
[route `auth` handler options](#route.options.auth).
Return value: none.
The default does not apply when a route config specifies `auth` as `false`, or has an
authentication strategy configured (contains the [`strategy`](#route.options.auth.strategy) or
[`strategies`](#route.options.auth.strategies) authentication settings). Otherwise, the route
authentication config is applied to the defaults.
Note that if the route has authentication configured, the default only applies at the time of
adding the route, not at runtime. This means that calling `server.auth.default()` after adding a
route with some authentication config will have no impact on the routes added prior. However, the
default will apply to routes added before `server.auth.default()` is called if those routes lack
any authentication config.
The default auth strategy configuration can be accessed via [`server.auth.settings.default`](#server.auth.settings.default).
To obtain the active authentication configuration of a route, use `server.auth.lookup(request.route)`.
```js
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
server.auth.scheme('custom', scheme);
server.auth.strategy('default', 'custom');
server.auth.default('default');
server.route({
method: 'GET',
path: '/',
handler: function (request, h) {
return request.auth.credentials.user;
}
});
```
### <a name="server.auth.scheme()" /> `server.auth.scheme(name, scheme)`
Registers an authentication scheme where:
- `name` - the scheme name.
- `scheme` - the method implementing the scheme with signature `function(server, options)` where:
- `server` - a reference to the server object the scheme is added to. Each auth strategy is given its own [`server.realm`](#server.realm) whose parent is the realm of the `server` in the call to [`server.auth.strategy()`](#server.auth.strategy()).
- `options` - (optional) the scheme `options` argument passed to
[`server.auth.strategy()`](#server.auth.strategy()) when instantiation a strategy.
Return value: none.
The `scheme` function must return an [authentication scheme object](#authentication-scheme) when
invoked.
#### Authentication scheme
An authentication scheme is an object with the following properties:
- `api` - (optional) object which is exposed via the [`server.auth.api`](#server.auth.api) object.
- `async authenticate(request, h)` - (required) a [lifecycle method](#lifecycle-methods) function
called for each incoming request configured with the authentication scheme. The method is
provided with two special toolkit methods for returning an authenticated or an unauthenticate
result:
- [`h.authenticated()`](#h.authenticated()) - indicate request authenticated successfully.
- [`h.unauthenticated()`](#h.unauthenticated()) - indicate request failed to authenticate.
- `async payload(request, h)` - (optional) a [lifecycle method](#lifecycle-methods) to authenticate
the request payload.
- `async response(request, h)` - (optional) a [lifecycle method](#lifecycle-methods) to decorate
the response with authentication headers before the response headers or payload is written.
- `async verify(auth)` - (optional) a method used to verify the authentication credentials provided
are still valid (e.g. not expired or revoked after the initial authentication) where:
- `auth` - the [`request.auth`](#request.auth) object containing the `credentials` and
`artifacts` objects returned by the scheme's `authenticate()` method.
- the method throws an `Error` when the credentials passed are no longer valid (e.g. expired or
revoked). Note that the method does not have access to the original request, only to the
credentials and artifacts produced by the `authenticate()` method.
- `options` - (optional) an object with the following keys:
- `payload` - if `true`, requires payload validation as part of the scheme and forbids routes
from disabling payload auth validation. Defaults to `false`.
When the scheme `authenticate()` method implementation throws an error or calls
[`h.unauthenticated()`](#h.unauthenticated()), the specifics of the error affect whether additional
authentication strategies will be attempted (if configured for the route). If the error includes a
message, no additional strategies will be attempted. If the `err` does not include a message but
does include the scheme name (e.g. `Boom.unauthorized(null, 'Custom')`), additional strategies will
be attempted in the order of preference (defined in the route configuration). If authentication
fails, the scheme names will be present in the 'WWW-Authenticate' header.
When the scheme `payload()` method throws an error with a message, it means payload validation
failed due to bad payload. If the error has no message but includes a scheme name (e.g.
`Boom.unauthorized(null, 'Custom')`), authentication may still be successful if the route
[`auth.payload`](#route.options.auth.payload) configuration is set to `'optional'`.
```js
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
const scheme = function (server, options) {
return {
authenticate: function (request, h) {
const req = request.raw.req;
const authorization = req.headers.authorization;
if (!authorization) {
throw Boom.unauthorized(null, 'Custom');
}
return h.authenticated({ credentials: { user: 'john' } });
}
};
};
server.auth.scheme('custom', scheme);
```
### <a name="server.auth.strategy()" /> `server.auth.strategy(name, scheme, [options])`
Registers an authentication strategy where:
- `name` - the strategy name.
- `scheme` - the scheme name (must be previously registered using
[`server.auth.scheme()`](#server.auth.scheme())).
- `options` - scheme options based on the scheme requirements.
Return value: none.
```js
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
server.auth.scheme('custom', scheme);
server.auth.strategy('default', 'custom');
server.route({
method: 'GET',
path: '/',
options: {
auth: 'default',
handler: function (request, h) {
return request.auth.credentials.user;
}
}
});
```
### <a name="server.auth.test()" /> `await server.auth.test(strategy, request)`
Tests a request against an authentication strategy where:
- `strategy` - the strategy name registered with [`server.auth.strategy()`](#server.auth.strategy()).
- `request` - the [request object](#request).
Return value: an object containing the authentication `credentials` and `artifacts` if authentication
was successful, otherwise throws an error.
Note that the `test()` method does not take into account the route authentication configuration. It
also does not perform payload authentication. It is limited to the basic strategy authentication
execution. It does not include verifying scope, entity, or other route properties.
```js
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
server.auth.scheme('custom', scheme);
server.auth.strategy('default', 'custom');
server.route({
method: 'GET',
path: '/',
handler: async function (request, h) {
try {
const { credentials, artifacts } = await request.server.auth.test('default', request);
return { status: true, user: credentials.name };
}
catch (err) {
return { status: false };
}
}
});
```
### <a name="server.auth.verify()" /> `await server.auth.verify(request)`
Verify a request's authentication credentials against an authentication strategy where:
- `request` - the [request object](#request).
Return value: nothing if verification was successful, otherwise throws an error.
Note that the `verify()` method does not take into account the route authentication configuration
or any other information from the request other than the `request.auth` object. It also does not
perform payload authentication. It is limited to verifying that the previously valid credentials
are still valid (e.g. have not been revoked or expired). It does not include verifying scope,
entity, or other route properties.
```js
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
server.auth.scheme('custom', scheme);
server.auth.strategy('default', 'custom');
server.route({
method: 'GET',
path: '/',
handler: async function (request, h) {
try {
const credentials = await request.server.auth.verify(request);
return { status: true, user: credentials.name };
}
catch (err) {
return { status: false };
}
}
});
```
### <a name="server.bind()" /> `server.bind(context)`
Sets a global context used as the default bind object when adding a route or an extension where:
- `context` - the object used to bind `this` in [lifecycle methods](#lifecycle-methods) such as
the [route handler](#route.options.handler) and [extension methods](#server.ext()). The context
is also made available as [`h.context`](#h.context).
Return value: none.
When setting a context inside a plugin, the context is applied only to methods set up by the
plugin. Note that the context applies only to routes and extensions added after it has been set.
Ignored if the method being bound is an arrow function.
```js
const handler = function (request, h) {
return this.message; // Or h.context.message
};
exports.plugin = {
name: 'example',
register: function (server, options) {
const bind = {
message: 'hello'
};
server.bind(bind);
server.route({ method: 'GET', path: '/', handler });
}
};
```
### <a name="server.cache()" /> `server.cache(options)`
Provisions a cache segment within the server cache facility where:
- `options` - [**catbox** policy](https://hapi.dev/family/catbox/api#policy) configuration where:
- `expiresIn` - relative expiration expressed in the number of milliseconds since the item was
saved in the cache. Cannot be used together with `expiresAt`.
- `expiresAt` - time of day expressed in 24h notation using the 'HH:MM' format, at which point
all cache records expire. Uses local time. Cannot be used together with `expiresIn`.
- `generateFunc` - a function used to generate a new cache item if one is not found in the
cache when calling `get()`. The method's signature is `async function(id, flags)` where:
- `id` - the `id` string or object provided to the `get()` method.
- `flags` - an object used to pass back additional flags to the cache where:
- `ttl` - the cache ttl value in milliseconds. Set to `0` to skip storing in the
cache. Defaults to the cache global policy.
- `staleIn` - number of milliseconds to mark an item stored in cache as stale and attempt to
regenerate it when `generateFunc` is provided. Must be less than `expiresIn`.
- `staleTimeout` - number of milliseconds to wait before checking if an item is stale.
- `generateTimeout` - number of milliseconds to wait before returning a timeout error when the
`generateFunc` function takes too long to return a value. When the value is eventually
returned, it is stored in the cache for future requests. Required if `generateFunc` is
present. Set to `false` to disable timeouts which may cause all `get()` requests to get stuck
forever.
- `generateOnReadError` - if `false`, an upstream cache read error will stop the `cache.get()`
method from calling the generate function and will instead pass back the cache error. Defaults
to `true`.
- `generateIgnoreWriteError` - if `false`, an upstream cache write error when calling
`cache.get()` will be passed back with the generated value when calling. Defaults to `true`.
- `dropOnError` - if `true`, an error or timeout in the `generateFunc` causes the stale value
to be evicted from the cache. Defaults to `true`.
- `pendingGenerateTimeout` - number of milliseconds while `generateFunc` call is in progress
for a given id, before a subsequent `generateFunc` call is allowed. Defaults to `0` (no
blocking of concurrent `generateFunc` calls beyond `staleTimeout`).
- `cache` - the cache name configured in [`server.cache`](#server.options.cache). Defaults to
the default cache.
- `segment` - string segment name, used to isolate cached items within the cache partition.
When called within a plugin, defaults to '!name' where 'name' is the plugin name. When called
within a server method, defaults to '#name' where 'name' is the server method name. Required
when called outside of a plugin.
- `shared` - if `true`, allows multiple cache provisions to share the same segment. Default to
`false`.
Return value: a [**catbox** policy](https://hapi.dev/family/catbox/api#policy) object.
```js
const Hapi = require('@hapi/hapi');
async function example() {
const server = Hapi.server({ port: 80 });
const cache = server.cache({ segment: 'countries', expiresIn: 60 * 60 * 1000 });
await cache.set('norway', { capital: 'oslo' });
const value = await cache.get('norway');
}
```
### <a name="server.cache.provision()" /> `await server.cache.provision(options)`
Provisions a server cache as described in [`server.cache`](#server.options.cache