This plugin adds full Express compatibility to Fastify, it exposes the same use
function of Express, and it allows you to use any Express middleware or application.
Note | This plugin should not be used as a long-term solution, it aims to help you have a smooth transition from Express to Fastify, but you should migrate your Express specific code to Fastify over time. |
Since Express does not support Node.js core HTTP/2 module, this plugin does not support HTTP/2 too. |
npm i @fastify/express
Register the plugin and start using your Express middlewares.
const Fastify = require('fastify')
async function build () {
const fastify = Fastify()
await fastify.register(require('@fastify/express'))
// do you know we also have cors support?
// https://github.com/fastify/fastify-cors
fastify.use(require('cors')())
// express.Application is also accessible
fastify.express.disabled('x-powered-by') // true
return fastify
}
build()
.then(fastify => fastify.listen({ port: 3000 }))
.catch(console.log)
You can register an entire Express application and make it work with Fastify. Remember, @fastify/express
is just express
under the covers and requires the same body parsers as you'd use in express
.
// index.js
const fastify = require('fastify')()
const express = require('express')
const router = express.Router()
router.use(function (req, res, next) {
res.setHeader('x-custom', true)
next()
})
router.get('/hello', (req, res) => {
res.status(201)
res.json({ hello: 'world' })
})
router.get('/foo', (req, res) => {
res.status(400)
res.json({ foo: 'bar' })
})
router.patch('/bar', (req, res) => {
if (!req.body || Object.keys(req.body).length === 0) {
res.status(400)
res.json({ msg: 'no req.body'})
} else {
res.status(200)
res.json(req.body)
}
})
router.use('*', (req, res) => {
res.status(404)
res.json({ msg: 'not found'})
})
fastify.register(require('@fastify/express'))
.after(() => {
fastify.use(express.urlencoded({extended: false})) // for Postman x-www-form-urlencoded
fastify.use(express.json())
fastify.use(router)
})
fastify.listen({ port: 3000 }, console.log)
Run node index.js
to start your server. Then run the following commands to ensure your server is working. Use the optional -v
flag in curl for verbose output.
me@computer ~ % curl -X GET http://localhost:3000/hello
{"hello":"world"}%
me@computer ~ % curl -X GET http://localhost:3000/foo
{"foo":"bar"}%
me@computer ~ % curl -X GET http://localhost:3000/bar
{"msg":"not found"}%
me@computer ~ % curl -X PATCH -H 'content-type:application/json' http://localhost:3000/bar
{"msg":"no req.body"}%
me@computer ~ % curl -X PATCH -H 'content-type:application/json' -d '{"foo2":"bar2"}' http://localhost:3000/bar
{"foo2":"bar2"}%
The encapsulation works as usual with Fastify, you can register the plugin in a subsystem and your express code will work only inside there, or you can declare the express plugin top level and register a middleware in a nested plugin, and the middleware will be executed only for the nested routes of the specific plugin.
Register the plugin in its own subsystem:
const fastify = require('fastify')()
fastify.register(subsystem)
async function subsystem (fastify, opts) {
await fastify.register(require('@fastify/express'))
fastify.use(require('cors')())
}
Register a middleware in a specific plugin:
const fastify = require('fastify')()
fastify
.register(require('@fastify/express'))
.register(subsystem)
async function subsystem (fastify, opts) {
fastify.use(require('cors')())
}
Every registered middleware will be run during the onRequest
hook phase, so the registration order is important.
Take a look at the Lifecycle documentation page to understand better how every request is executed.
const fastify = require('fastify')()
fastify
.register(require('@fastify/express'))
.register(subsystem)
async function subsystem (fastify, opts) {
fastify.addHook('onRequest', async (req, reply) => {
console.log('first')
})
fastify.use((req, res, next) => {
console.log('second')
next()
})
fastify.addHook('onRequest', async (req, reply) => {
console.log('third')
})
}
If you need to run a middleware only under certain path(s), just pass the path as first parameter to use and you are done!
const fastify = require('fastify')()
const path = require('path')
const serveStatic = require('serve-static')
fastify
.register(require('@fastify/express'))
.register(subsystem)
async function subsystem (fastify, opts) {
// Single path
fastify.use('/css', serveStatic(path.join(__dirname, '/assets')))
// Wildcard path
fastify.use('/css/*', serveStatic(path.join(__dirname, '/assets')))
// Multiple paths
fastify.use(['/css', '/js'], serveStatic(path.join(__dirname, '/assets')))
}
To use this module with TypeScript, make sure to install @types/express
.
You will need to add "types": ["@fastify/express"]
to your tsconfig.json file when using require
to import the plugin.
Fastify offers some alternatives to the most commonly used middlewares, following, you can find a list.
Express Middleware | Fastify Plugin |
---|---|
helmet |
@fastify/helmet |
cors |
@fastify/cors |
serve-static |
@fastify/static |
body-parser library incompatible with fastify-express
, when you have fastify
routes and any express
middlewares.
Any POST requests with body, which body-parser
will try to parse, will be hangs up.
Example application:
const Fastify = require('fastify')
const Express = require('express')
const expressPlugin = require('@fastify/express')
const bodyParser = require('body-parser')
const fastify = Fastify()
const express = Express()
express.use(bodyParser.urlencoded({ extended: false }))
await fastify.register(expressPlugin)
fastify.use(express)
// this route will never reply
fastify.post('/hello', (req, reply) => {
return { hello: 'world' }
})
For this case, you need to remove body-parser
, install @fastify/formbody
and change @fastify/express
options:
const Fastify = require('fastify')
const Express = require('express')
const expressPlugin = require('@fastify/express')
const fastifyFormBody = require('@fastify/formbody')
const fastify = Fastify()
const express = Express()
await fastify.register(fastifyFormBody)
await fastify.register(expressPlugin, {
// run express after `@fastify/formbody` logic
expressHook: 'preHandler'
})
fastify.use(express)
// it works!
fastify.post('/hello', (req, reply) => {
return { hello: 'world' }
})
Licensed under MIT.
express
license