strong-tie/inbound-calls
0
1<h1 align="center">Fastify</h1>2 3## Factory4<a id="factory"></a>5 6The Fastify module exports a factory function that is used to create new7<code><b>Fastify server</b></code> instances. This factory function accepts an8options object which is used to customize the resulting instance. This document9describes the properties available in that options object.10 11- [Factory](#factory)12 - [`http`](#http)13 - [`http2`](#http2)14 - [`https`](#https)15 - [`connectionTimeout`](#connectiontimeout)16 - [`keepAliveTimeout`](#keepalivetimeout)17 - [`forceCloseConnections`](#forcecloseconnections)18 - [`maxRequestsPerSocket`](#maxrequestspersocket)19 - [`requestTimeout`](#requesttimeout)20 - [`ignoreTrailingSlash`](#ignoretrailingslash)21 - [`ignoreDuplicateSlashes`](#ignoreduplicateslashes)22 - [`maxParamLength`](#maxparamlength)23 - [`bodyLimit`](#bodylimit)24 - [`onProtoPoisoning`](#onprotopoisoning)25 - [`onConstructorPoisoning`](#onconstructorpoisoning)26 - [`logger`](#logger)27 - [`loggerInstance`](#loggerInstance)28 - [`disableRequestLogging`](#disablerequestlogging)29 - [`serverFactory`](#serverfactory)30 - [`caseSensitive`](#casesensitive)31 - [`allowUnsafeRegex`](#allowunsaferegex)32 - [`requestIdHeader`](#requestidheader)33 - [`requestIdLogLabel`](#requestidloglabel)34 - [`genReqId`](#genreqid)35 - [`trustProxy`](#trustproxy)36 - [`pluginTimeout`](#plugintimeout)37 - [`querystringParser`](#querystringparser)38 - [`exposeHeadRoutes`](#exposeheadroutes)39 - [`constraints`](#constraints)40 - [`return503OnClosing`](#return503onclosing)41 - [`ajv`](#ajv)42 - [`serializerOpts`](#serializeropts)43 - [`http2SessionTimeout`](#http2sessiontimeout)44 - [`frameworkErrors`](#frameworkerrors)45 - [`clientErrorHandler`](#clienterrorhandler)46 - [`rewriteUrl`](#rewriteurl)47 - [`useSemicolonDelimiter`](#usesemicolondelimiter)48- [Instance](#instance)49 - [Server Methods](#server-methods)50 - [server](#server)51 - [after](#after)52 - [ready](#ready)53 - [listen](#listen)54 - [`listenTextResolver`](#listentextresolver)55 - [addresses](#addresses)56 - [routing](#routing)57 - [route](#route)58 - [hasRoute](#hasroute)59 - [findRoute](#findroute)60 - [close](#close)61 - [decorate\*](#decorate)62 - [register](#register)63 - [addHook](#addhook)64 - [prefix](#prefix)65 - [pluginName](#pluginname)66 - [hasPlugin](#hasplugin)67 - [listeningOrigin](#listeningorigin)68 - [log](#log)69 - [version](#version)70 - [inject](#inject)71 - [addHttpMethod](#addHttpMethod)72 - [addSchema](#addschema)73 - [getSchemas](#getschemas)74 - [getSchema](#getschema)75 - [setReplySerializer](#setreplyserializer)76 - [setValidatorCompiler](#setvalidatorcompiler)77 - [setSchemaErrorFormatter](#setschemaerrorformatter)78 - [setSerializerCompiler](#setserializercompiler)79 - [validatorCompiler](#validatorcompiler)80 - [serializerCompiler](#serializercompiler)81 - [schemaErrorFormatter](#schemaerrorformatter)82 - [schemaController](#schemacontroller)83 - [setNotFoundHandler](#setnotfoundhandler)84 - [setErrorHandler](#seterrorhandler)85 - [setChildLoggerFactory](#setchildloggerfactory)86 - [setGenReqId](#setGenReqId)87 - [addConstraintStrategy](#addconstraintstrategy)88 - [hasConstraintStrategy](#hasconstraintstrategy)89 - [printRoutes](#printroutes)90 - [printPlugins](#printplugins)91 - [addContentTypeParser](#addcontenttypeparser)92 - [hasContentTypeParser](#hascontenttypeparser)93 - [removeContentTypeParser](#removecontenttypeparser)94 - [removeAllContentTypeParsers](#removeallcontenttypeparsers)95 - [getDefaultJsonParser](#getdefaultjsonparser)96 - [defaultTextParser](#defaulttextparser)97 - [errorHandler](#errorhandler)98 - [childLoggerFactory](#childloggerfactory)99 - [Symbol.asyncDispose](#symbolasyncdispose)100 - [initialConfig](#initialconfig)101 102### `http`103<a id="factory-http"></a>104 105+ Default: `null`106 107An object used to configure the server's listening socket. The options108are the same as the Node.js core [`createServer`109method](https://nodejs.org/docs/latest-v20.x/api/http.html#httpcreateserveroptions-requestlistener).110 111This option is ignored if options [`http2`](#factory-http2) or112[`https`](#factory-https) are set.113 114### `http2`115<a id="factory-http2"></a>116 117+ Default: `false`118 119If `true` Node.js core's120[HTTP/2](https://nodejs.org/dist/latest-v20.x/docs/api/http2.html) module is121used for binding the socket.122 123### `https`124<a id="factory-https"></a>125 126+ Default: `null`127 128An object used to configure the server's listening socket for TLS. The options129are the same as the Node.js core [`createServer`130method](https://nodejs.org/dist/latest-v20.x/docs/api/https.html#https_https_createserver_options_requestlistener).131When this property is `null`, the socket will not be configured for TLS.132 133This option also applies when the [`http2`](#factory-http2) option is set.134 135### `connectionTimeout`136<a id="factory-connection-timeout"></a>137 138+ Default: `0` (no timeout)139 140Defines the server timeout in milliseconds. See documentation for141[`server.timeout`142property](https://nodejs.org/api/http.html#http_server_timeout) to understand143the effect of this option.144 145When `serverFactory` option is specified this option is ignored.146 147### `keepAliveTimeout`148<a id="factory-keep-alive-timeout"></a>149 150+ Default: `72000` (72 seconds)151 152Defines the server keep-alive timeout in milliseconds. See documentation for153[`server.keepAliveTimeout`154property](https://nodejs.org/api/http.html#http_server_keepalivetimeout) to155understand the effect of this option. This option only applies when HTTP/1 is in156use.157 158When `serverFactory` option is specified this option is ignored.159 160### `forceCloseConnections`161<a id="forcecloseconnections"></a>162 163+ Default: `"idle"` if the HTTP server allows it, `false` otherwise164 165When set to `true`, upon [`close`](#close) the server will iterate the current166persistent connections and [destroy their167sockets](https://nodejs.org/dist/latest-v16.x/docs/api/net.html#socketdestroyerror).168 169> **Warning**170> Connections are not inspected to determine if requests have171> been completed.172 173Fastify will prefer the HTTP server's174[`closeAllConnections`](https://nodejs.org/dist/latest-v18.x/docs/api/http.html#servercloseallconnections)175method if supported, otherwise, it will use internal connection tracking.176 177When set to `"idle"`, upon [`close`](#close) the server will iterate the current178persistent connections which are not sending a request or waiting for a response179and destroy their sockets. The value is only supported if the HTTP server180supports the181[`closeIdleConnections`](https://nodejs.org/dist/latest-v18.x/docs/api/http.html#servercloseidleconnections)182method, otherwise attempting to set it will throw an exception.183 184### `maxRequestsPerSocket`185<a id="factory-max-requests-per-socket"></a>186 187+ Default: `0` (no limit)188 189Defines the maximum number of requests a socket can handle before closing keep190alive connection. See [`server.maxRequestsPerSocket`191property](https://nodejs.org/dist/latest/docs/api/http.html#http_server_maxrequestspersocket)192to understand the effect of this option. This option only applies when HTTP/1.1193is in use. Also, when `serverFactory` option is specified, this option is194ignored.195 196> **Note**197> At the time of writing, only node >= v16.10.0 supports this option.198 199### `requestTimeout`200<a id="factory-request-timeout"></a>201 202+ Default: `0` (no limit)203 204Defines the maximum number of milliseconds for receiving the entire request from205the client. See [`server.requestTimeout`206property](https://nodejs.org/dist/latest/docs/api/http.html#http_server_requesttimeout)207to understand the effect of this option.208 209When `serverFactory` option is specified, this option is ignored.210It must be set to a non-zero value (e.g. 120 seconds) to protect against potential211Denial-of-Service attacks in case the server is deployed without a reverse proxy212in front.213 214> **Note**215> At the time of writing, only node >= v14.11.0 supports this option216 217### `ignoreTrailingSlash`218<a id="factory-ignore-slash"></a>219 220+ Default: `false`221 222Fastify uses [find-my-way](https://github.com/delvedor/find-my-way) to handle223routing. By default, Fastify will take into account the trailing slashes.224Paths like `/foo` and `/foo/` are treated as different paths. If you want to225change this, set this flag to `true`. That way, both `/foo` and `/foo/` will226point to the same route. This option applies to *all* route registrations for227the resulting server instance.228 229```js230const fastify = require('fastify')({231 ignoreTrailingSlash: true232})233 234// registers both "/foo" and "/foo/"235fastify.get('/foo/', function (req, reply) {236 reply.send('foo')237})238 239// registers both "/bar" and "/bar/"240fastify.get('/bar', function (req, reply) {241 reply.send('bar')242})243```244 245### `ignoreDuplicateSlashes`246<a id="factory-ignore-duplicate-slashes"></a>247 248+ Default: `false`249 250Fastify uses [find-my-way](https://github.com/delvedor/find-my-way) to handle251routing. You can use `ignoreDuplicateSlashes` option to remove duplicate slashes252from the path. It removes duplicate slashes in the route path and the request253URL. This option applies to *all* route registrations for the resulting server254instance.255 256When `ignoreTrailingSlash` and `ignoreDuplicateSlashes` are both set257to `true` Fastify will remove duplicate slashes, and then trailing slashes,258meaning `//a//b//c//` will be converted to `/a/b/c`.259 260```js261const fastify = require('fastify')({262 ignoreDuplicateSlashes: true263})264 265// registers "/foo/bar/"266fastify.get('///foo//bar//', function (req, reply) {267 reply.send('foo')268})269```270 271### `maxParamLength`272<a id="factory-max-param-length"></a>273 274+ Default: `100`275 276You can set a custom length for parameters in parametric (standard, regex, and277multi) routes by using `maxParamLength` option; the default value is 100278characters. If the maximum length limit is reached, the not found route will279be invoked.280 281This can be useful especially if you have a regex-based route, protecting you282against [ReDoS283attacks](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS).284 285### `bodyLimit`286<a id="factory-body-limit"></a>287 288+ Default: `1048576` (1MiB)289 290Defines the maximum payload, in bytes, the server is allowed to accept.291The default body reader sends [`FST_ERR_CTP_BODY_TOO_LARGE`](./Errors.md#fst_err_ctp_body_too_large)292reply, if the size of the body exceeds this limit.293If [`preParsing` hook](./Hooks.md#preparsing) is provided, this limit is applied294to the size of the stream the hook returns (i.e. the size of "decoded" body).295 296### `onProtoPoisoning`297<a id="factory-on-proto-poisoning"></a>298 299+ Default: `'error'`300 301Defines what action the framework must take when parsing a JSON object with302`__proto__`. This functionality is provided by303[secure-json-parse](https://github.com/fastify/secure-json-parse). See304[Prototype Poisoning](../Guides/Prototype-Poisoning.md) for more details about305prototype poisoning attacks.306 307Possible values are `'error'`, `'remove'`, or `'ignore'`.308 309### `onConstructorPoisoning`310<a id="factory-on-constructor-poisoning"></a>311 312+ Default: `'error'`313 314Defines what action the framework must take when parsing a JSON object with315`constructor`. This functionality is provided by316[secure-json-parse](https://github.com/fastify/secure-json-parse). See317[Prototype Poisoning](../Guides/Prototype-Poisoning.md) for more details about318prototype poisoning attacks.319 320Possible values are `'error'`, `'remove'`, or `'ignore'`.321 322### `logger`323<a id="factory-logger"></a>324 325Fastify includes built-in logging via the [Pino](https://getpino.io/) logger.326This property is used to configure the internal logger instance.327 328The possible values this property may have are:329 330+ Default: `false`. The logger is disabled. All logging methods will point to a331 null logger [abstract-logging](https://npm.im/abstract-logging) instance.332 333+ `object`: a standard Pino [options334 object](https://github.com/pinojs/pino/blob/c77d8ec5ce/docs/API.md#constructor).335 This will be passed directly to the Pino constructor. If the following336 properties are not present on the object, they will be added accordingly:337 * `level`: the minimum logging level. If not set, it will be set to338 `'info'`.339 * `serializers`: a hash of serialization functions. By default, serializers340 are added for `req` (incoming request objects), `res` (outgoing response341 objects), and `err` (standard `Error` objects). When a log method receives342 an object with any of these properties then the respective serializer will343 be used for that property. For example:344 ```js345 fastify.get('/foo', function (req, res) {346 req.log.info({req}) // log the serialized request object347 res.send('foo')348 })349 ```350 Any user-supplied serializer will override the default serializer of the351 corresponding property.352 353### `loggerInstance`354<a id="factory-logger-instance"></a>355 356+ Default: `null`357 358A custom logger instance. The logger must be a Pino instance or conform to the359Pino interface by having the following methods: `info`, `error`, `debug`,360`fatal`, `warn`, `trace`, `child`. For example:361 ```js362 const pino = require('pino')();363 364 const customLogger = {365 info: function (o, ...n) {},366 warn: function (o, ...n) {},367 error: function (o, ...n) {},368 fatal: function (o, ...n) {},369 trace: function (o, ...n) {},370 debug: function (o, ...n) {},371 child: function() {372 const child = Object.create(this);373 child.pino = pino.child(...arguments);374 return child;375 },376 };377 378 const fastify = require('fastify')({logger: customLogger});379 ```380 381### `disableRequestLogging`382<a id="factory-disable-request-logging"></a>383 384+ Default: `false`385 386When logging is enabled, Fastify will issue an `info` level log387message when a request is received and when the response for that request has388been sent. By setting this option to `true`, these log messages will be389disabled. This allows for more flexible request start and end logging by390attaching custom `onRequest` and `onResponse` hooks.391 392The other log entries that will be disabled are:393- an error log written by the default `onResponse` hook on reply callback errors394- the error and info logs written by the `defaultErrorHandler`395on error management396- the info log written by the `fourOhFour` handler when a397non existent route is requested398 399Other log messages emitted by Fastify will stay enabled,400like deprecation warnings and messages401emitted when requests are received while the server is closing.402 403```js404// Examples of hooks to replicate the disabled functionality.405fastify.addHook('onRequest', (req, reply, done) => {406 req.log.info({ url: req.raw.url, id: req.id }, 'received request')407 done()408})409 410fastify.addHook('onResponse', (req, reply, done) => {411 req.log.info({ url: req.raw.originalUrl, statusCode: reply.raw.statusCode }, 'request completed')412 done()413})414```415 416### `serverFactory`417<a id="custom-http-server"></a>418 419You can pass a custom HTTP server to Fastify by using the `serverFactory`420option.421 422`serverFactory` is a function that takes a `handler` parameter, which takes the423`request` and `response` objects as parameters, and an options object, which is424the same you have passed to Fastify.425 426```js427const serverFactory = (handler, opts) => {428 const server = http.createServer((req, res) => {429 handler(req, res)430 })431 432 return server433}434 435const fastify = Fastify({ serverFactory })436 437fastify.get('/', (req, reply) => {438 reply.send({ hello: 'world' })439})440 441fastify.listen({ port: 3000 })442```443 444Internally Fastify uses the API of Node core HTTP server, so if you are using a445custom server you must be sure to have the same API exposed. If not, you can446enhance the server instance inside the `serverFactory` function before the447`return` statement.448 449### `caseSensitive`450<a id="factory-case-sensitive"></a>451 452+ Default: `true`453 454When `true` routes are registered as case-sensitive. That is, `/foo`455is not equal to `/Foo`.456When `false` then routes are case-insensitive.457 458Please note that setting this option to `false` goes against459[RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.1).460 461By setting `caseSensitive` to `false`, all paths will be matched as lowercase,462but the route parameters or wildcards will maintain their original letter463casing.464This option does not affect query strings, please refer to465[`querystringParser`](#querystringparser) to change their handling.466 467```js468fastify.get('/user/:username', (request, reply) => {469 // Given the URL: /USER/NodeJS470 console.log(request.params.username) // -> 'NodeJS'471})472```473 474### `allowUnsafeRegex`475<a id="factory-allow-unsafe-regex"></a>476 477+ Default `false`478 479Disabled by default, so routes only allow safe regular expressions. To use480unsafe expressions, set `allowUnsafeRegex` to `true`.481 482```js483fastify.get('/user/:id(^([0-9]+){4}$)', (request, reply) => {484 // Throws an error without allowUnsafeRegex = true485})486```487 488### `requestIdHeader`489<a id="factory-request-id-header"></a>490 491+ Default: `'request-id'`492 493The header name used to set the request-id. See [the494request-id](./Logging.md#logging-request-id) section.495Setting `requestIdHeader` to `true` will set the `requestIdHeader` to496`"request-id"`.497Setting `requestIdHeader` to a non-empty string will use498the specified string as the `requestIdHeader`.499By default `requestIdHeader` is set to `false` and will immediately use [genReqId](#genreqid).500Setting `requestIdHeader` to an empty String (`""`) will set the501requestIdHeader to `false`.502 503+ Default: `false`504 505```js506const fastify = require('fastify')({507 requestIdHeader: 'x-custom-id', // -> use 'X-Custom-Id' header if available508 //requestIdHeader: false, // -> always use genReqId509})510```511 512### `requestIdLogLabel`513<a id="factory-request-id-log-label"></a>514 515+ Default: `'reqId'`516 517Defines the label used for the request identifier when logging the request.518 519### `genReqId`520<a id="factory-gen-request-id"></a>521 522+ Default: `value of 'request-id' header if provided or monotonically increasing523 integers`524 525Function for generating the request-id. It will receive the _raw_ incoming526request as a parameter. This function is expected to be error-free.527 528Especially in distributed systems, you may want to override the default ID529generation behavior as shown below. For generating `UUID`s you may want to check530out [hyperid](https://github.com/mcollina/hyperid).531 532> **Note**533> `genReqId` will be not called if the header set in534> <code>[requestIdHeader](#requestidheader)</code> is available (defaults to535> 'request-id').536 537```js538let i = 0539const fastify = require('fastify')({540 genReqId: function (req) { return i++ }541})542```543 544### `trustProxy`545<a id="factory-trust-proxy"></a>546 547+ Default: `false`548+ `true/false`: Trust all proxies (`true`) or do not trust any proxies549 (`false`).550+ `string`: Trust only given IP/CIDR (e.g. `'127.0.0.1'`). May be a list of551 comma separated values (e.g. `'127.0.0.1,192.168.1.1/24'`).552+ `Array<string>`: Trust only given IP/CIDR list (e.g. `['127.0.0.1']`).553+ `number`: Trust the nth hop from the front-facing proxy server as the client.554+ `Function`: Custom trust function that takes `address` as first argument555 ```js556 function myTrustFn(address, hop) {557 return address === '1.2.3.4' || hop === 1558 }559 ```560 561By enabling the `trustProxy` option, Fastify will know that it is sitting behind562a proxy and that the `X-Forwarded-*` header fields may be trusted, which563otherwise may be easily spoofed.564 565```js566const fastify = Fastify({ trustProxy: true })567```568 569For more examples, refer to the570[`@fastify/proxy-addr`](https://www.npmjs.com/package/@fastify/proxy-addr) package.571 572You may access the `ip`, `ips`, `host` and `protocol` values on the573[`request`](./Request.md) object.574 575```js576fastify.get('/', (request, reply) => {577 console.log(request.ip)578 console.log(request.ips)579 console.log(request.host)580 console.log(request.protocol)581})582```583 584> **Note**585> If a request contains multiple `x-forwarded-host` or `x-forwarded-proto`586> headers, it is only the last one that is used to derive `request.hostname`587> and `request.protocol`.588 589### `pluginTimeout`590<a id="plugin-timeout"></a>591 592+ Default: `10000`593 594The maximum amount of time in *milliseconds* in which a plugin can load. If not,595[`ready`](#ready) will complete with an `Error` with code596`'ERR_AVVIO_PLUGIN_TIMEOUT'`. When set to `0`, disables this check. This597controls [avvio](https://www.npmjs.com/package/avvio) 's `timeout` parameter.598 599### `querystringParser`600<a id="factory-querystring-parser"></a>601 602The default query string parser that Fastify uses is the Node.js's core603`querystring` module.604 605You can use this option to use a custom parser, such as606[`qs`](https://www.npmjs.com/package/qs).607 608If you only want the keys (and not the values) to be case insensitive we609recommend using a custom parser to convert only the keys to lowercase.610 611```js612const qs = require('qs')613const fastify = require('fastify')({614 querystringParser: str => qs.parse(str)615})616```617 618You can also use Fastify's default parser but change some handling behavior,619like the example below for case insensitive keys and values:620 621```js622const querystring = require('node:querystring')623const fastify = require('fastify')({624 querystringParser: str => querystring.parse(str.toLowerCase())625})626```627 628### `exposeHeadRoutes`629<a id="exposeHeadRoutes"></a>630 631+ Default: `true`632 633Automatically creates a sibling `HEAD` route for each `GET` route defined. If634you want a custom `HEAD` handler without disabling this option, make sure to635define it before the `GET` route.636 637### `constraints`638<a id="constraints"></a>639 640Fastify's built-in route constraints are provided by `find-my-way`, which641allows constraining routes by `version` or `host`. You can add new constraint642strategies, or override the built-in strategies, by providing a `constraints`643object with strategies for `find-my-way`. You can find more information on644constraint strategies in the645[find-my-way](https://github.com/delvedor/find-my-way) documentation.646 647```js648const customVersionStrategy = {649 storage: function () {650 const versions = {}651 return {652 get: (version) => { return versions[version] || null },653 set: (version, store) => { versions[version] = store }654 }655 },656 deriveVersion: (req, ctx) => {657 return req.headers['accept']658 }659}660 661const fastify = require('fastify')({662 constraints: {663 version: customVersionStrategy664 }665})666```667 668### `return503OnClosing`669<a id="factory-return-503-on-closing"></a>670 671+ Default: `true`672 673Returns 503 after calling `close` server method. If `false`, the server routes674the incoming request as usual.675 676### `ajv`677<a id="factory-ajv"></a>678 679Configure the Ajv v8 instance used by Fastify without providing a custom one.680The default configuration is explained in the681[#schema-validator](./Validation-and-Serialization.md#schema-validator) section.682 683```js684const fastify = require('fastify')({685 ajv: {686 customOptions: {687 removeAdditional: 'all' // Refer to [ajv options](https://ajv.js.org/options.html#removeadditional)688 },689 plugins: [690 require('ajv-merge-patch'),691 [require('ajv-keywords'), 'instanceof']692 // Usage: [plugin, pluginOptions] - Plugin with options693 // Usage: plugin - Plugin without options694 ]695 }696})697```698 699### `serializerOpts`700<a id="serializer-opts"></a>701 702Customize the options of the default703[`fast-json-stringify`](https://github.com/fastify/fast-json-stringify#options)704instance that serializes the response's payload:705 706```js707const fastify = require('fastify')({708 serializerOpts: {709 rounding: 'ceil'710 }711})712```713 714### `http2SessionTimeout`715<a id="http2-session-timeout"></a>716 717+ Default: `72000`718 719Set a default720[timeout](https://nodejs.org/api/http2.html#http2sessionsettimeoutmsecs-callback)721to every incoming HTTP/2 session in milliseconds. The session will be closed on722the timeout.723 724This option is needed to offer a graceful "close" experience when using725HTTP/2. The low default has been chosen to mitigate denial of service attacks.726When the server is behind a load balancer or can scale automatically this value727can be increased to fit the use case. Node core defaults this to `0`.728 729### `frameworkErrors`730<a id="framework-errors"></a>731 732+ Default: `null`733 734Fastify provides default error handlers for the most common use cases. It is735possible to override one or more of those handlers with custom code using this736option.737 738> **Note**739> Only `FST_ERR_BAD_URL` and `FST_ERR_ASYNC_CONSTRAINT` are implemented at present.740 741```js742const fastify = require('fastify')({743 frameworkErrors: function (error, req, res) {744 if (error instanceof FST_ERR_BAD_URL) {745 res.code(400)746 return res.send("Provided url is not valid")747 } else if(error instanceof FST_ERR_ASYNC_CONSTRAINT) {748 res.code(400)749 return res.send("Provided header is not valid")750 } else {751 res.send(err)752 }753 }754})755```756 757### `clientErrorHandler`758<a id="client-error-handler"></a>759 760Set a761[clientErrorHandler](https://nodejs.org/api/http.html#http_event_clienterror)762that listens to `error` events emitted by client connections and responds with a763`400`.764 765It is possible to override the default `clientErrorHandler` using this option.766 767+ Default:768```js769function defaultClientErrorHandler (err, socket) {770 if (err.code === 'ECONNRESET') {771 return772 }773 774 const body = JSON.stringify({775 error: http.STATUS_CODES['400'],776 message: 'Client Error',777 statusCode: 400778 })779 this.log.trace({ err }, 'client error')780 781 if (socket.writable) {782 socket.end([783 'HTTP/1.1 400 Bad Request',784 `Content-Length: ${body.length}`,785 `Content-Type: application/json\r\n\r\n${body}`786 ].join('\r\n'))787 }788}789```790 791> **Note**792> `clientErrorHandler` operates with raw sockets. The handler is expected to793> return a properly formed HTTP response that includes a status line, HTTP headers794> and a message body. Before attempting to write the socket, the handler should795> check if the socket is still writable as it may have already been destroyed.796 797```js798const fastify = require('fastify')({799 clientErrorHandler: function (err, socket) {800 const body = JSON.stringify({801 error: {802 message: 'Client error',803 code: '400'804 }805 })806 807 // `this` is bound to fastify instance808 this.log.trace({ err }, 'client error')809 810 // the handler is responsible for generating a valid HTTP response811 socket.end([812 'HTTP/1.1 400 Bad Request',813 `Content-Length: ${body.length}`,814 `Content-Type: application/json\r\n\r\n${body}`815 ].join('\r\n'))816 }817})818```819 820### `rewriteUrl`821<a id="rewrite-url"></a>822 823Set a sync callback function that must return a string that allows rewriting824URLs. This is useful when you are behind a proxy that changes the URL.825Rewriting a URL will modify the `url` property of the `req` object.826 827Note that `rewriteUrl` is called _before_ routing, it is not encapsulated and it828is an instance-wide configuration.829 830```js831// @param {object} req The raw Node.js HTTP request, not the `FastifyRequest` object.832// @this Fastify The root Fastify instance (not an encapsulated instance).833// @returns {string} The path that the request should be mapped to.834function rewriteUrl (req) {835 if (req.url === '/hi') {836 this.log.debug({ originalUrl: req.url, url: '/hello' }, 'rewrite url');837 return '/hello'838 } else {839 return req.url;840 }841}842```843 844### `useSemicolonDelimiter`845<a id="use-semicolon-delimiter"></a>846 847+ Default `false`848 849Fastify uses [find-my-way](https://github.com/delvedor/find-my-way) which supports,850separating the path and query string with a `;` character (code 59), e.g. `/dev;foo=bar`.851This decision originated from [delvedor/find-my-way#76]852(https://github.com/delvedor/find-my-way/issues/76). Thus, this option will support853backwards compatiblilty for the need to split on `;`. To enable support for splitting854on `;` set `useSemicolonDelimiter` to `true`.855 856```js857const fastify = require('fastify')({858 useSemicolonDelimiter: true859})860 861fastify.get('/dev', async (request, reply) => {862 // An example request such as `/dev;foo=bar`863 // Will produce the following query params result `{ foo = 'bar' }`864 return request.query865})866```867 868 869## Instance870 871### Server Methods872 873#### server874<a id="server"></a>875 876`fastify.server`: The Node core877[server](https://nodejs.org/api/http.html#http_class_http_server) object as878returned by the [**`Fastify factory function`**](#factory).879 880> **Warning**881> If utilized improperly, certain Fastify features could be disrupted.882> It is recommended to only use it for attaching listeners.883 884#### after885<a id="after"></a>886 887Invoked when the current plugin and all the plugins that have been registered888within it have finished loading. It is always executed before the method889`fastify.ready`.890 891```js892fastify893 .register((instance, opts, done) => {894 console.log('Current plugin')895 done()896 })897 .after(err => {898 console.log('After current plugin')899 })900 .register((instance, opts, done) => {901 console.log('Next plugin')902 done()903 })904 .ready(err => {905 console.log('Everything has been loaded')906 })907```908 909In case `after()` is called without a function, it returns a `Promise`:910 911```js912fastify.register(async (instance, opts) => {913 console.log('Current plugin')914})915 916await fastify.after()917console.log('After current plugin')918 919fastify.register(async (instance, opts) => {920 console.log('Next plugin')921})922 923await fastify.ready()924 925console.log('Everything has been loaded')926```927 928#### ready929<a id="ready"></a>930 931Function called when all the plugins have been loaded. It takes an error932parameter if something went wrong.933```js934fastify.ready(err => {935 if (err) throw err936})937```938If it is called without any arguments, it will return a `Promise`:939 940```js941fastify.ready().then(() => {942 console.log('successfully booted!')943}, (err) => {944 console.log('an error happened', err)945})946```947 948#### listen949<a id="listen"></a>950 951Starts the server and internally waits for the `.ready()` event. The signature952is `.listen([options][, callback])`. Both the `options` object and the953`callback` parameters extend the [Node.js954core](https://nodejs.org/api/net.html#serverlistenoptions-callback) options955object. Thus, all core options are available with the following additional956Fastify specific options:957 958### `listenTextResolver`959<a id="listen-text-resolver"></a>960 961Set an optional resolver for the text to log after server has been successfully962started.963It is possible to override the default `Server listening at [address]` log964entry using this option.965 966```js967server.listen({968 port: 9080,969 listenTextResolver: (address) => { return `Prometheus metrics server is listening at ${address}` }970})971```972 973By default, the server will listen on the address(es) resolved by `localhost`974when no specific host is provided. If listening on any available interface is975desired, then specifying `0.0.0.0` for the address will listen on all IPv4976addresses. The following table details the possible values for `host` when977targeting `localhost`, and what the result of those values for `host` will be.978 979 Host | IPv4 | IPv6980 --------------|------|-------981 `::` | ✅<sup>*</sup> | ✅982 `::` + [`ipv6Only`](https://nodejs.org/api/net.html#serverlistenoptions-callback) | 🚫 | ✅983 `0.0.0.0` | ✅ | 🚫984 `localhost` | ✅ | ✅985 `127.0.0.1` | ✅ | 🚫986 `::1` | 🚫 | ✅987 988<sup>*</sup> Using `::` for the address will listen on all IPv6 addresses and,989depending on OS, may also listen on [all IPv4990addresses](https://nodejs.org/api/net.html#serverlistenport-host-backlog-callback).991 992Be careful when deciding to listen on all interfaces; it comes with inherent993[security994risks](https://web.archive.org/web/20170831174611/https://snyk.io/blog/mongodb-hack-and-secure-defaults/).995 996The default is to listen on `port: 0` (which picks the first available open997port) and `host: 'localhost'`:998 999```js1000fastify.listen((err, address) => {1001 if (err) {1002 fastify.log.error(err)1003 process.exit(1)1004 }1005})1006```1007 1008Specifying an address is also supported:1009 1010```js1011fastify.listen({ port: 3000, host: '127.0.0.1' }, (err, address) => {1012 if (err) {1013 fastify.log.error(err)1014 process.exit(1)1015 }1016})1017```1018 1019If no callback is provided a Promise is returned:1020 1021```js1022fastify.listen({ port: 3000 })1023 .then((address) => console.log(`server listening on ${address}`))1024 .catch(err => {1025 console.log('Error starting server:', err)1026 process.exit(1)1027 })1028```1029 1030When deploying to a Docker, and potentially other, containers, it is advisable1031to listen on `0.0.0.0` because they do not default to exposing mapped ports to1032`localhost`:1033 1034```js1035fastify.listen({ port: 3000, host: '0.0.0.0' }, (err, address) => {1036 if (err) {1037 fastify.log.error(err)1038 process.exit(1)1039 }1040})1041```1042 1043If the `port` is omitted (or is set to zero), a random available port is1044automatically chosen (available via `fastify.server.address().port`).1045 1046The default options of listen are:1047 1048```js1049fastify.listen({1050 port: 0,1051 host: 'localhost',1052 exclusive: false,1053 readableAll: false,1054 writableAll: false,1055 ipv6Only: false1056}, (err) => {})1057```1058 1059#### addresses1060<a id="addresses"></a>1061 1062This method returns an array of addresses that the server is listening on. If1063you call it before `listen()` is called or after the `close()` function, it will1064return an empty array.1065 1066```js1067await fastify.listen({ port: 8080 })1068const addresses = fastify.addresses()1069// [1070// { port: 8080, family: 'IPv6', address: '::1' },1071// { port: 8080, family: 'IPv4', address: '127.0.0.1' }1072// ]1073```1074 1075Note that the array contains the `fastify.server.address()` too.1076 1077#### routing1078<a id="routing"></a>1079 1080Method to access the `lookup` method of the internal router and match the1081request to the appropriate handler:1082 1083```js1084fastify.routing(req, res)1085```1086 1087#### route1088<a id="route"></a>1089 1090Method to add routes to the server, it also has shorthand functions, check1091[here](./Routes.md).1092 1093#### hasRoute1094<a id="hasRoute"></a>1095 1096Method to check if a route is already registered to the internal router. It1097expects an object as the payload. `url` and `method` are mandatory fields. It1098is possible to also specify `constraints`. The method returns `true` if the1099route is registered or `false` if not.1100 1101```js1102const routeExists = fastify.hasRoute({1103 url: '/',1104 method: 'GET',1105 constraints: { version: '1.0.0' } // optional1106})1107 1108if (routeExists === false) {1109 // add route1110}1111```1112 1113#### findRoute1114<a id="findRoute"></a>1115 1116Method to retrieve a route already registered to the internal router. It1117expects an object as the payload. `url` and `method` are mandatory fields. It1118is possible to also specify `constraints`.1119The method returns a route object or `null` if the route cannot be found.1120 1121```js1122const route = fastify.findRoute({1123 url: '/artists/:artistId',1124 method: 'GET',1125 constraints: { version: '1.0.0' } // optional1126})1127 1128if (route !== null) {1129 // perform some route checks1130 console.log(route.params) // `{artistId: ':artistId'}`1131}1132```1133 1134 1135#### close1136<a id="close"></a>1137 1138`fastify.close(callback)`: call this function to close the server instance and1139run the [`'onClose'`](./Hooks.md#on-close) hook.1140 1141Calling `close` will also cause the server to respond to every new incoming1142request with a `503` error and destroy that request. See [`return503OnClosing`1143flags](#factory-return-503-on-closing) for changing this behavior.1144 1145If it is called without any arguments, it will return a Promise:1146 1147```js1148fastify.close().then(() => {1149 console.log('successfully closed!')1150}, (err) => {1151 console.log('an error happened', err)1152})1153```1154 1155#### decorate*1156<a id="decorate"></a>1157 1158Function useful if you need to decorate the fastify instance, Reply or Request,1159check [here](./Decorators.md).1160 1161#### register1162<a id="register"></a>1163 1164Fastify allows the user to extend its functionality with plugins. A plugin can1165be a set of routes, a server decorator, or whatever, check [here](./Plugins.md).1166 1167#### addHook1168<a id="addHook"></a>1169 1170Function to add a specific hook in the lifecycle of Fastify, check1171[here](./Hooks.md).1172 1173#### prefix1174<a id="prefix"></a>1175 1176The full path that will be prefixed to a route.1177 1178Example:1179 1180```js1181fastify.register(function (instance, opts, done) {1182 instance.get('/foo', function (request, reply) {1183 // Will log "prefix: /v1"1184 request.log.info('prefix: %s', instance.prefix)1185 reply.send({ prefix: instance.prefix })1186 })1187 1188 instance.register(function (instance, opts, done) {1189 instance.get('/bar', function (request, reply) {1190 // Will log "prefix: /v1/v2"1191 request.log.info('prefix: %s', instance.prefix)1192 reply.send({ prefix: instance.prefix })1193 })1194 1195 done()1196 }, { prefix: '/v2' })1197 1198 done()1199}, { prefix: '/v1' })1200```