strong-tie/inbound-calls
0
1# V3 Migration Guide2 3This guide is intended to help with migration from Fastify v2 to v3.4 5Before beginning please ensure that any deprecation warnings from v2 are fixed.6All v2 deprecations have been removed and they will no longer work after7upgrading. ([#1750](https://github.com/fastify/fastify/pull/1750))8 9## Breaking changes10 11### Changed middleware support ([#2014](https://github.com/fastify/fastify/pull/2014))12 13From Fastify v3, middleware support does not come out-of-the-box with the14framework itself.15 16If you use Express middleware in your application, please install and register17the [`@fastify/express`](https://github.com/fastify/fastify-express) or18[`@fastify/middie`](https://github.com/fastify/middie) plugin before doing so.19 20**v2:**21 22```js23// Using the Express `cors` middleware in Fastify v2.24fastify.use(require('cors')());25```26 27**v3:**28 29```js30// Using the Express `cors` middleware in Fastify v3.31await fastify.register(require('@fastify/express'));32fastify.use(require('cors')());33```34 35### Changed logging serialization ([#2017](https://github.com/fastify/fastify/pull/2017))36 37The logging [Serializers](../Reference/Logging.md) have been updated to now38Fastify [`Request`](../Reference/Request.md) and39[`Reply`](../Reference/Reply.md) objects instead of native ones.40 41Any custom serializers must be updated if they rely upon `request` or `reply`42properties that are present on the native objects but not the Fastify objects.43 44**v2:**45 46```js47const fastify = require('fastify')({48 logger: {49 serializers: {50 res(res) {51 return {52 statusCode: res.statusCode,53 customProp: res.customProp54 };55 }56 }57 }58});59```60 61**v3:**62 63```js64const fastify = require('fastify')({65 logger: {66 serializers: {67 res(reply) {68 return {69 statusCode: reply.statusCode, // No change required70 customProp: reply.raw.customProp // Log custom property from res object71 };72 }73 }74 }75});76```77 78### Changed schema substitution ([#2023](https://github.com/fastify/fastify/pull/2023))79 80The non-standard `replace-way` shared schema support has been removed. This81feature has been replaced with JSON Schema specification compliant `$ref` based82substitution. To help understand this change read [Validation and Serialization83in Fastify84v3](https://dev.to/eomm/validation-and-serialization-in-fastify-v3-2e8l).85 86**v2:**87 88```js89const schema = {90 body: 'schemaId#'91};92fastify.route({ method, url, schema, handler });93```94 95**v3:**96 97```js98const schema = {99 body: {100 $ref: 'schemaId#'101 }102};103fastify.route({ method, url, schema, handler });104```105 106### Changed schema validation options ([#2023](https://github.com/fastify/fastify/pull/2023))107 108The `setSchemaCompiler` and `setSchemaResolver` options have been replaced with109the `setValidatorCompiler` to enable future tooling improvements. To help110understand this change read [Validation and Serialization in Fastify111v3](https://dev.to/eomm/validation-and-serialization-in-fastify-v3-2e8l).112 113**v2:**114 115```js116const fastify = Fastify();117const ajv = new AJV();118ajv.addSchema(schemaA);119ajv.addSchema(schemaB);120 121fastify.setSchemaCompiler(schema => ajv.compile(schema));122fastify.setSchemaResolver(ref => ajv.getSchema(ref).schema);123```124 125**v3:**126 127```js128const fastify = Fastify();129const ajv = new AJV();130ajv.addSchema(schemaA);131ajv.addSchema(schemaB);132 133fastify.setValidatorCompiler(({ schema, method, url, httpPart }) =>134 ajv.compile(schema)135);136```137 138### Changed preParsing hook behavior ([#2286](https://github.com/fastify/fastify/pull/2286))139 140From Fastify v3, the behavior of the `preParsing` hook will change slightly141to support request payload manipulation.142 143The hook now takes an additional argument, `payload`, and therefore the new hook144signature is `fn(request, reply, payload, done)` or `async fn(request, reply,145payload)`.146 147The hook can optionally return a new stream via `done(null, stream)` or148returning the stream in case of async functions.149 150If the hook returns a new stream, it will be used instead of the original one in151subsequent hooks. A sample use case for this is handling compressed requests.152 153The new stream should add the `receivedEncodedLength` property to the stream154that should reflect the actual data size received from the client. For instance,155in a compressed request it should be the size of the compressed payload. This156property can (and should) be dynamically updated during `data` events.157 158The old syntax of Fastify v2 without payload is supported but it is deprecated.159 160### Changed hooks behavior ([#2004](https://github.com/fastify/fastify/pull/2004))161 162From Fastify v3, the behavior of `onRoute` and `onRegister` hooks will change163slightly to support hook encapsulation.164 165- `onRoute` - The hook will be called asynchronously. The hook is now inherited166 when registering a new plugin within the same encapsulation scope. Thus, this167 hook should be registered _before_ registering any plugins.168- `onRegister` - Same as the onRoute hook. The only difference is that now the169 very first call will no longer be the framework itself, but the first170 registered plugin.171 172### Changed Content Type Parser syntax ([#2286](https://github.com/fastify/fastify/pull/2286))173 174In Fastify v3 the content type parsers now have a single signature for parsers.175 176The new signatures are `fn(request, payload, done)` or `async fn(request,177payload)`. Note that `request` is now a Fastify request, not an178`IncomingMessage`. The payload is, by default, a stream. If the `parseAs` option179is used in `addContentTypeParser`, then `payload` reflects the option value180(string or buffer).181 182The old signatures `fn(req, [done])` or `fn(req, payload, [done])` (where `req`183is `IncomingMessage`) are still supported but are deprecated.184 185### Changed TypeScript support186 187The type system was changed in Fastify version 3. The new type system introduces188generic constraining and defaulting, plus a new way to define schema types such189as a request body, querystring, and more!190 191**v2:**192 193```ts194interface PingQuerystring {195 foo?: number;196}197 198interface PingParams {199 bar?: string;200}201 202interface PingHeaders {203 a?: string;204}205 206interface PingBody {207 baz?: string;208}209 210server.get<PingQuerystring, PingParams, PingHeaders, PingBody>(211 '/ping/:bar',212 opts,213 (request, reply) => {214 console.log(request.query); // This is of type `PingQuerystring`215 console.log(request.params); // This is of type `PingParams`216 console.log(request.headers); // This is of type `PingHeaders`217 console.log(request.body); // This is of type `PingBody`218 }219);220```221 222**v3:**223 224```ts225server.get<{226 Querystring: PingQuerystring;227 Params: PingParams;228 Headers: PingHeaders;229 Body: PingBody;230}>('/ping/:bar', opts, async (request, reply) => {231 console.log(request.query); // This is of type `PingQuerystring`232 console.log(request.params); // This is of type `PingParams`233 console.log(request.headers); // This is of type `PingHeaders`234 console.log(request.body); // This is of type `PingBody`235});236```237 238### Manage uncaught exception ([#2073](https://github.com/fastify/fastify/pull/2073))239 240In sync route handlers, if an error was thrown the server crashed by design241without calling the configured `.setErrorHandler()`. This has changed and now242all unexpected errors in sync and async routes are managed.243 244**v2:**245 246```js247fastify.setErrorHandler((error, request, reply) => {248 // this is NOT called249 reply.send(error)250})251fastify.get('/', (request, reply) => {252 const maybeAnArray = request.body.something ? [] : 'I am a string'253 maybeAnArray.substr() // Thrown: [].substr is not a function and crash the server254})255```256 257**v3:**258 259```js260fastify.setErrorHandler((error, request, reply) => {261 // this IS called262 reply.send(error)263})264fastify.get('/', (request, reply) => {265 const maybeAnArray = request.body.something ? [] : 'I am a string'266 maybeAnArray.substr() // Thrown: [].substr is not a function, but it is handled267})268```269 270## Further additions and improvements271 272- Hooks now have consistent context regardless of how they are registered273 ([#2005](https://github.com/fastify/fastify/pull/2005))274- Deprecated `request.req` and `reply.res` for275 [`request.raw`](../Reference/Request.md) and276 [`reply.raw`](../Reference/Reply.md)277 ([#2008](https://github.com/fastify/fastify/pull/2008))278- Removed `modifyCoreObjects` option279 ([#2015](https://github.com/fastify/fastify/pull/2015))280- Added [`connectionTimeout`](../Reference/Server.md#factory-connection-timeout)281 option ([#2086](https://github.com/fastify/fastify/pull/2086))282- Added [`keepAliveTimeout`](../Reference/Server.md#factory-keep-alive-timeout)283 option ([#2086](https://github.com/fastify/fastify/pull/2086))284- Added async-await support for [plugins](../Reference/Plugins.md#async-await)285 ([#2093](https://github.com/fastify/fastify/pull/2093))286- Added the feature to throw object as error287 ([#2134](https://github.com/fastify/fastify/pull/2134))288 