Fastify v2 is coming to town

Courtesy of Rodrigo Ardilha https://unsplash.com/photos/TYtbqZdYtc8

Doing everything right at the first try is not just impossible, but also weird.
In the past months, we have gathered your feedback, issues, and needs and we worked behind the scenes to shape Fastify v2 to address all of them.

Starting today Fastify v2 will be released as Release Candidate, so you can try it and tell us if there is still something we must fix or improve before cut the final release. During the RC period, we will also update all of our official plugins to support at best Fastify v2 and use the new features to improve them. You can install it now with npm install fastify@next.

Speaking of new features and breaking changes, following you can find the list of all the major changes we did, with the link to their pull request, a brief description, and a code example.

Let us know about any compatibility and upgrade issues at https://github.com/fastify/help.

Added onError hook #1236

Add a new application hook called onError, which a developer can use to track all the errors that Fastify is sending to the user. This can be super useful also for sending errors to an external tracer or to support an APM (Application Performance Monitoring) solution.
In Fastify v1 we can’t do that easily because the setErrorHandler can be overwritten and the onSend hook receives the already serialized payload.
In Fastify v1 there is no way to get the error object and be 100% sure that your code will never be overwritten.

fastify.addHook(‘onError’, (request, reply, error, next) => {
// some code
next()
})

Move all _ prefixed properties to Symbols in next #1237 #1128

Internal fastify properties that were prefixed with _ in key objects, such as Request and Reply, are now using Symbols. This provides a more clear separation between the internals and your application, clearly identifying which properties you can use.

Plugins can now receive both /prefix and prefix/ #1228

The ability to prefix all the routes defined in a plugin is a key feature of Fastify. In v2 we have resolved a problem that made it impossible to set up a route for both /prefix and /prefix/, as follows:

const fastify = require(‘fastify’)()
fastify.register(function (instance, options, next) {
// the route will be called for both ‘/english/’ and ‘/english’
instance.get(‘/’, (req, reply) => {
reply.send({ greet: ‘hello’ })
})
next()
}, { prefix: ‘/english’ })
fastify.listen(8000, function (err, address) {
if (err) throw err
console.log(`server listening on ${address}`)
})

Default error handler that logs the error #1135

In Fastify v1, we logged all errors independently if there was (or not) a custom error handler (via setErrorHandler()). In Fastify v2, this behavior has been moved to the error handler. This means that an error handler is now responsible for logging the error itself.


fastify.setErrorHandler(function (error, request, reply) {
request.log.warn(error) // this is needed now
var statusCode = error.statusCode >= 400 ? error.statusCode : 500
reply
.code(statusCode)
.type(‘text/plain’)
.send(statusCode >= 500
? ‘Internal server error’
: error.message
)
})

Ensure Reply#serialize uses custom serializer #1163

reply.serialize(payload) serializes the payload using the custom serializer, if one is set.

Better error management #1168

We can sum up this new feature with one word: standardization!
From Fastify v2 the errors will no longer be generated inline, but they will be instances of custom errors classes.
You can access the full error list from require('fastify/errors') .

Bumped avvio to 6.0.0. #1201

The new version of avvio removes the instance from the onClose hook as the first parameter.

fastify.addHook('onClose', (done) => {
// some code
done()
})

Added preValidation hook #1153

This hook was needed because there was no way to run the authentication logic before the validation but after the onRequest hook or the middlewares. There are cases where you may not want to expose your validation logic to unauthenticated requests, this hook fixes that issue.

fastify.addHook('preValidation', (request, reply, next) => {
// some code
next()
})

Change basePath to prefix #1183

A basePath property was populated with the prefix option when passed to a plugin. This has now been renamed to prefix, to provide a more intuitive API. The use of basePath is now deprecated.

Separate logging and reqId options #1164 #1166

From Fastify v2 you must create the custom request id as a top-level option in the Fastify configuration, and no longer inside the logger configuration. This is still supported, but Fastify will log a warning. The option will be dropped from Fastify v3.

Change the default plugin timeout to 10 seconds instead of 0 #1145

Each plugin now has 10 seconds to load or it will error. This solves a long-standing issue with Fastify’s bootstrapping phase: forgetting to call a callback or resolving a promise would lead to a stuck load phase with no way to easily debug it.

Pino v5 #1065

Fastify now uses Pino v5 internally, for better and more performant logging with zero cost log redaction. Check it out at https://www.nearform.com/blog/announcing-pino-v5-0-0/.

As an example, the following snippet will print all the incoming headers but the authorization.

const fastify = require(‘fastify’)({
logger: {
stream: stream,
redact: [‘req.headers.authorization’],
level: ‘info’,
serializers: {
req(req) {
return {
method: req.method,
url: req.url,
headers: req.headers,
hostname: req.hostname,
remoteAddress: req.ip,
remotePort: req.connection.remotePort
}
}
}
}
})

Updated Not found handling #1084

If one of your routes returns a 404 error, from Fastify v2 will be handled by the customErrorHandler and not the notFoundHandler. You can still route requests to the notFoundHandler via reply.callNotFound(). The notFoundHandler will be used only for router generated 404s.

Hooks: always use Fastify core objects #1066

This was a long-awaited “feature”, in Fastify v1 onRequest and onResponse have different signature and objects, which leads to confusion and slightly complex internals.

From Fastify v2 we have fixed that, and now every hook will expose the exact same signature. The middlewares will continue to expose the default Node.js core objects to allow compatibility with Express middlewares. If you are not using Express middlewares, we highly recommend using Fastify hooks.

fastify.addHook(‘onRequest’, function (request, reply, next) {
// request and reply are the core Fastify objects
next()
})
fastify.addHook(‘onResponse’, function (request, reply, next) {
// request and reply are the core Fastify objects
next()
})
fastify.use(function (req, res, next) {
// req and res are the Node core objects
next()
})

Remove `req.id` in serializer #1032

There is no more the req.id property in the logs, but only reqId (less duplication, less space, more speed!).

Removed url.parse and added custom querystring parser support #1270

Since url.parse will be deprecated from Node.js v12, we decided to remove it from the codebase and use the Node.js’s core querystring module instead. With this change, the querystring parsing is twice faster than before!
We have also exposed a new configuration option (querystringParser) to change the default querystring parser if needed.

Extended support of cross-platform builds and yarn official support #1226

Due to the extended support of Azure pipelines, our CI is more performant and we are able to test cross-platform (Linux/yarn and Windows/npm) with a single setup in a timely fashion. This also brings official yarn support for Node 8 and Node 10. We thank AppVeyor for the support in the last year of Windows testing. We are also keeping our travis-ci integration for Linux/npm for the time being.

Courtesy of lee bernd https://unsplash.com/photos/INlDrPFQIQc

Acknowledgments

More than 1700 commits, more than 90 releases, more than 450 forks, used in production by more than 8 companies, more than 260k downloads, and 87 officially recognized plugins.

All this work wouldn’t be possible without the help of our fantastic team, which we would like to thank for all their hard work!
allevo, cemremengu, delvedor, evanshortiss, lmammino, jsumners, mcollina, nwoltman, starptech, and trivikr.
We also want to thank all of our amazing contributors, for all the bug reporting, pull requests and for have believed in our project!

Fastify v2 is covered by our LTS support cycle, organized as follows: at least six months of active support plus six months of security fixes (after the release of Fastify v3), while Fastify v1 will reach EOL on June first.

Happy coding!

The Fastify Team