JaxNode January 2021
// Require the framework and instantiate it
const fastify = require('fastify')({ logger: true });
// Declare a route
fastify.get('/', async (request, reply) => {
return { hello: 'world' }
});
// Run the server!
const start = async () => {
try {
await fastify.listen(3000)
} catch (err) {
fastify.log.error(err)
process.exit(1)
}
}
start();
schema: {
// request needs to have a querystring with a `name` parameter
querystring: {
name: { type: 'string' }
},
// the response needs to be an object with
// an `hello` property of type 'string'
response: {
200: {
type: 'object',
properties: {
hello: { type: 'string' }
}
}
}
}
Feature | Express | Hapi | Fastify |
---|---|---|---|
router | ✔ | ✔ | ✔ |
middleware | ✔ | ❌ | ✔ |
plugins | ❌ | ✔ | ✔ |
validation | ❌ | ✔ | ✔ |
hooks | ❌ | ✔ | ✔ |
decorators | ❌ | ✔ | ✔ |
logging | ❌ | ✔ | ✔ |
async/await | ❌ | ✔ | ✔ |
req/sec | 18k | 20k | 36k |
// our-first-route.js
async function routes (fastify, options) {
fastify.get('/', async (request, reply) => {
return { hello: 'world' }
})
}
module.exports = routes
// server.js
const fastify = require('fastify')({
logger: true
})
fastify.register(require('./our-first-route'))
fastify.listen(3000, function (err, address) {
if (err) {
fastify.log.error(err)
process.exit(1)
}
fastify.log.info(`server listening on ${address}`)
})
// Decorate request with a 'user' property
fastify.decorateRequest('user', '')
// Update our property
fastify.addHook('preHandler', (req, reply, done) => {
req.user = 'Dave Growl'
done()
})
// And finally access it
fastify.get('/', (req, reply) => {
reply.send(`Hello, ${req.user}!`)
})
fastify.route({
method: 'GET',
url: '/',
schema: {
querystring: {
name: { type: 'string' },
excitement: { type: 'integer' }
},
response: {
200: {
type: 'object',
properties: {
hello: { type: 'string' }
}
}
}
},
handler: function (request, reply) {
reply.send({ hello: 'world' })
}
})
Routes long form
const opts = {
schema: {
response: {
200: {
type: 'object',
properties: {
hello: { type: 'string' }
}
}
}
}
}
fastify.get('/', opts, (request, reply) => {
reply.send({ hello: 'world' })
})
Long Form
// server.js
const fastify = require('fastify')()
fastify.register(require('./routes/v1/users'), { prefix: '/v1' })
fastify.register(require('./routes/v2/users'), { prefix: '/v2' })
fastify.listen(3000)
// routes/v1/users.js
module.exports = function (fastify, opts, done) {
fastify.get('/user', handler_v1)
done()
}
// routes/v2/users.js
module.exports = function (fastify, opts, done) {
fastify.get('/user', handler_v2)
done()
}
Prefix Example
fastify.register(require('point-of-view'), {
engine: {
ejs: require('ejs')
},
root: path.join(__dirname, 'view'),
layout: 'template',
viewExt: 'html', // it will add the extension to all the views
options: {}
})
onRequest
preParsing
preValidation
preHandler
preSerialization
onError
onSend
onResponse
onTimeout
onReady
onClose
onRoute
onRegister
Hook Types
fastify.addHook('preParsing', async (request, reply, payload) => {
// Some code
await asyncMethod()
return newPayload
})
await fastify.register(require('fastify-express'))
fastify.use(require('cors')())
fastify.use(require('dns-prefetch-control')())
fastify.use(require('frameguard')())
fastify.use(require('hsts')())
fastify.use(require('ienoopen')())
fastify.use(require('x-xss-protection')())
Express Middleware Example
await fastify.register(require('middie'))
fastify.use(require('cors')())
middie example