You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					557 lines
				
				14 KiB
			
		
		
			
		
	
	
					557 lines
				
				14 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								<h1 align="center">Fastify</h1>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Getting Started
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Hello! Thank you for checking out Fastify!
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This document aims to be a gentle introduction to the framework and its
							 | 
						||
| 
								 | 
							
								features. It is an elementary preface with examples and links to other parts of
							 | 
						||
| 
								 | 
							
								the documentation.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Let's start!
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Install
							 | 
						||
| 
								 | 
							
								<a id="install"></a>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Install with npm:
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								npm i fastify --save
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								Install with yarn:
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								yarn add fastify
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Your first server
							 | 
						||
| 
								 | 
							
								<a id="first-server"></a>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Let's write our first server:
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								// Require the framework and instantiate it
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// ESM
							 | 
						||
| 
								 | 
							
								import Fastify from 'fastify'
							 | 
						||
| 
								 | 
							
								const fastify = Fastify({
							 | 
						||
| 
								 | 
							
								  logger: true
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								// CommonJs
							 | 
						||
| 
								 | 
							
								const fastify = require('fastify')({
							 | 
						||
| 
								 | 
							
								  logger: true
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Declare a route
							 | 
						||
| 
								 | 
							
								fastify.get('/', function (request, reply) {
							 | 
						||
| 
								 | 
							
								  reply.send({ hello: 'world' })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Run the server!
							 | 
						||
| 
								 | 
							
								fastify.listen(3000, function (err, address) {
							 | 
						||
| 
								 | 
							
								  if (err) {
							 | 
						||
| 
								 | 
							
								    fastify.log.error(err)
							 | 
						||
| 
								 | 
							
								    process.exit(1)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  // Server is now listening on ${address}
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Do you prefer to use `async/await`? Fastify supports it out-of-the-box.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								*(We also suggest using
							 | 
						||
| 
								 | 
							
								[make-promises-safe](https://github.com/mcollina/make-promises-safe) to avoid
							 | 
						||
| 
								 | 
							
								file descriptor and memory leaks.)*
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								// ESM
							 | 
						||
| 
								 | 
							
								import Fastify from 'fastify'
							 | 
						||
| 
								 | 
							
								const fastify = Fastify({
							 | 
						||
| 
								 | 
							
								  logger: true
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								// CommonJs
							 | 
						||
| 
								 | 
							
								const fastify = require('fastify')({
							 | 
						||
| 
								 | 
							
								  logger: true
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.get('/', async (request, reply) => {
							 | 
						||
| 
								 | 
							
								  return { hello: 'world' }
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const start = async () => {
							 | 
						||
| 
								 | 
							
								  try {
							 | 
						||
| 
								 | 
							
								    await fastify.listen(3000)
							 | 
						||
| 
								 | 
							
								  } catch (err) {
							 | 
						||
| 
								 | 
							
								    fastify.log.error(err)
							 | 
						||
| 
								 | 
							
								    process.exit(1)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								start()
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Awesome, that was easy.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Unfortunately, writing a complex application requires significantly more code
							 | 
						||
| 
								 | 
							
								than this example. A classic problem when you are building a new application is
							 | 
						||
| 
								 | 
							
								how to handle multiple files, asynchronous bootstrapping, and the architecture
							 | 
						||
| 
								 | 
							
								of your code.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Fastify offers an easy platform that helps to solve all of the problems outlined
							 | 
						||
| 
								 | 
							
								above, and more!
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								> ## Note
							 | 
						||
| 
								 | 
							
								> The above examples, and subsequent examples in this document, default to
							 | 
						||
| 
								 | 
							
								> listening *only* on the localhost `127.0.0.1` interface. To listen on all
							 | 
						||
| 
								 | 
							
								> available IPv4 interfaces the example should be modified to listen on
							 | 
						||
| 
								 | 
							
								> `0.0.0.0` like so:
							 | 
						||
| 
								 | 
							
								>
							 | 
						||
| 
								 | 
							
								> ```js
							 | 
						||
| 
								 | 
							
								> fastify.listen(3000, '0.0.0.0', function (err, address) {
							 | 
						||
| 
								 | 
							
								>   if (err) {
							 | 
						||
| 
								 | 
							
								>     fastify.log.error(err)
							 | 
						||
| 
								 | 
							
								>     process.exit(1)
							 | 
						||
| 
								 | 
							
								>   }
							 | 
						||
| 
								 | 
							
								>   fastify.log.info(`server listening on ${address}`)
							 | 
						||
| 
								 | 
							
								> })
							 | 
						||
| 
								 | 
							
								> ```
							 | 
						||
| 
								 | 
							
								>
							 | 
						||
| 
								 | 
							
								> Similarly, specify `::1` to accept only local connections via IPv6. Or specify
							 | 
						||
| 
								 | 
							
								> `::` to accept connections on all IPv6 addresses, and, if the operating system
							 | 
						||
| 
								 | 
							
								> supports it, also on all IPv4 addresses.
							 | 
						||
| 
								 | 
							
								>
							 | 
						||
| 
								 | 
							
								> When deploying to a Docker (or another type of) container using `0.0.0.0` or
							 | 
						||
| 
								 | 
							
								> `::` would be the easiest method for exposing the application.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Your first plugin
							 | 
						||
| 
								 | 
							
								<a id="first-plugin"></a>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								As with JavaScript, where everything is an object, with Fastify everything is a
							 | 
						||
| 
								 | 
							
								plugin.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Before digging into it, let's see how it works!
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Let's declare our basic server, but instead of declaring the route inside the
							 | 
						||
| 
								 | 
							
								entry point, we'll declare it in an external file (check out the [route
							 | 
						||
| 
								 | 
							
								declaration](../Reference/Routes.md) docs).
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								// ESM
							 | 
						||
| 
								 | 
							
								import Fastify from 'fastify'
							 | 
						||
| 
								 | 
							
								import firstRoute from './our-first-route'
							 | 
						||
| 
								 | 
							
								const fastify = Fastify({
							 | 
						||
| 
								 | 
							
								  logger: true
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.register(firstRoute)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.listen(3000, function (err, address) {
							 | 
						||
| 
								 | 
							
								  if (err) {
							 | 
						||
| 
								 | 
							
								    fastify.log.error(err)
							 | 
						||
| 
								 | 
							
								    process.exit(1)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  // Server is now listening on ${address}
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								// CommonJs
							 | 
						||
| 
								 | 
							
								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)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  // Server is now listening on ${address}
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								// our-first-route.js
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								async function routes (fastify, options) {
							 | 
						||
| 
								 | 
							
								  fastify.get('/', async (request, reply) => {
							 | 
						||
| 
								 | 
							
								    return { hello: 'world' }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = routes
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								In this example, we used the `register` API, which is the core of the Fastify
							 | 
						||
| 
								 | 
							
								framework. It is the only way to add routes, plugins, et cetera.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								At the beginning of this guide, we noted that Fastify provides a foundation that
							 | 
						||
| 
								 | 
							
								assists with asynchronous bootstrapping of your application. Why is this
							 | 
						||
| 
								 | 
							
								important?
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Consider the scenario where a database connection is needed to handle data
							 | 
						||
| 
								 | 
							
								storage. The database connection needs to be available before the server is
							 | 
						||
| 
								 | 
							
								accepting connections. How do we address this problem?
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								A typical solution is to use a complex callback, or promises - a system that
							 | 
						||
| 
								 | 
							
								will mix the framework API with other libraries and the application code.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Fastify handles this internally, with minimum effort!
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Let's rewrite the above example with a database connection.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								First, install `fastify-plugin` and `@fastify/mongodb`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								npm i --save fastify-plugin @fastify/mongodb
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								**server.js**
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								// ESM
							 | 
						||
| 
								 | 
							
								import Fastify from 'fastify'
							 | 
						||
| 
								 | 
							
								import dbConnector from './our-db-connector'
							 | 
						||
| 
								 | 
							
								import firstRoute from './our-first-route'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const fastify = Fastify({
							 | 
						||
| 
								 | 
							
								  logger: true
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								fastify.register(dbConnector)
							 | 
						||
| 
								 | 
							
								fastify.register(firstRoute)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.listen(3000, function (err, address) {
							 | 
						||
| 
								 | 
							
								  if (err) {
							 | 
						||
| 
								 | 
							
								    fastify.log.error(err)
							 | 
						||
| 
								 | 
							
								    process.exit(1)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  // Server is now listening on ${address}
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								// CommonJs
							 | 
						||
| 
								 | 
							
								const fastify = require('fastify')({
							 | 
						||
| 
								 | 
							
								  logger: true
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.register(require('./our-db-connector'))
							 | 
						||
| 
								 | 
							
								fastify.register(require('./our-first-route'))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.listen(3000, function (err, address) {
							 | 
						||
| 
								 | 
							
								  if (err) {
							 | 
						||
| 
								 | 
							
								    fastify.log.error(err)
							 | 
						||
| 
								 | 
							
								    process.exit(1)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  // Server is now listening on ${address}
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								**our-db-connector.js**
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								// ESM
							 | 
						||
| 
								 | 
							
								import fastifyPlugin from 'fastify-plugin'
							 | 
						||
| 
								 | 
							
								import fastifyMongo from '@fastify/mongodb'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								async function dbConnector (fastify, options) {
							 | 
						||
| 
								 | 
							
								  fastify.register(fastifyMongo, {
							 | 
						||
| 
								 | 
							
								    url: 'mongodb://localhost:27017/test_database'
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Wrapping a plugin function with fastify-plugin exposes the decorators
							 | 
						||
| 
								 | 
							
								// and hooks, declared inside the plugin to the parent scope.
							 | 
						||
| 
								 | 
							
								module.exports = fastifyPlugin(dbConnector)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								// CommonJs
							 | 
						||
| 
								 | 
							
								const fastifyPlugin = require('fastify-plugin')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								async function dbConnector (fastify, options) {
							 | 
						||
| 
								 | 
							
								  fastify.register(require('@fastify/mongodb'), {
							 | 
						||
| 
								 | 
							
								    url: 'mongodb://localhost:27017/test_database'
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Wrapping a plugin function with fastify-plugin exposes the decorators
							 | 
						||
| 
								 | 
							
								// and hooks, declared inside the plugin to the parent scope.
							 | 
						||
| 
								 | 
							
								module.exports = fastifyPlugin(dbConnector)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								**our-first-route.js**
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								async function routes (fastify, options) {
							 | 
						||
| 
								 | 
							
								  const collection = fastify.mongo.db.collection('test_collection')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.get('/', async (request, reply) => {
							 | 
						||
| 
								 | 
							
								    return { hello: 'world' }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.get('/animals', async (request, reply) => {
							 | 
						||
| 
								 | 
							
								    const result = await collection.find().toArray()
							 | 
						||
| 
								 | 
							
								    if (result.length === 0) {
							 | 
						||
| 
								 | 
							
								      throw new Error('No documents found')
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return result
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.get('/animals/:animal', async (request, reply) => {
							 | 
						||
| 
								 | 
							
								    const result = await collection.findOne({ animal: request.params.animal })
							 | 
						||
| 
								 | 
							
								    if (!result) {
							 | 
						||
| 
								 | 
							
								      throw new Error('Invalid value')
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return result
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const animalBodyJsonSchema = {
							 | 
						||
| 
								 | 
							
								    type: 'object',
							 | 
						||
| 
								 | 
							
								    required: ['animal'],
							 | 
						||
| 
								 | 
							
								    properties: {
							 | 
						||
| 
								 | 
							
								      animal: { type: 'string' },
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const schema = {
							 | 
						||
| 
								 | 
							
								    body: animalBodyJsonSchema,
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.post('/animals', { schema }, async (request, reply) => {
							 | 
						||
| 
								 | 
							
								    // we can use the `request.body` object to get the data sent by the client
							 | 
						||
| 
								 | 
							
								    const result = await collection.insertOne({ animal: request.body.animal })
							 | 
						||
| 
								 | 
							
								    return result
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = routes
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Wow, that was fast!
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Let's recap what we have done here since we've introduced some new concepts.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								As you can see, we used `register` for both the database connector and the
							 | 
						||
| 
								 | 
							
								registration of the routes.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This is one of the best features of Fastify, it will load your plugins in the
							 | 
						||
| 
								 | 
							
								same order you declare them, and it will load the next plugin only once the
							 | 
						||
| 
								 | 
							
								current one has been loaded. In this way, we can register the database connector
							 | 
						||
| 
								 | 
							
								in the first plugin and use it in the second *(read
							 | 
						||
| 
								 | 
							
								[here](../Reference/Plugins.md#handle-the-scope) to understand how to handle the
							 | 
						||
| 
								 | 
							
								scope of a plugin)*.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Plugin loading starts when you call `fastify.listen()`, `fastify.inject()` or
							 | 
						||
| 
								 | 
							
								`fastify.ready()`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The MongoDB plugin uses the `decorate` API to add custom objects to the Fastify
							 | 
						||
| 
								 | 
							
								instance, making them available for use everywhere. Use of this API is
							 | 
						||
| 
								 | 
							
								encouraged to facilitate easy code reuse and to decrease code or logic
							 | 
						||
| 
								 | 
							
								duplication.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								To dig deeper into how Fastify plugins work, how to develop new plugins, and for
							 | 
						||
| 
								 | 
							
								details on how to use the whole Fastify API to deal with the complexity of
							 | 
						||
| 
								 | 
							
								asynchronously bootstrapping an application, read [the hitchhiker's guide to
							 | 
						||
| 
								 | 
							
								plugins](./Plugins-Guide.md).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Loading order of your plugins
							 | 
						||
| 
								 | 
							
								<a id="plugin-loading-order"></a>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								To guarantee consistent and predictable behavior of your application, we highly
							 | 
						||
| 
								 | 
							
								recommend to always load your code as shown below:
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								└── plugins (from the Fastify ecosystem)
							 | 
						||
| 
								 | 
							
								└── your plugins (your custom plugins)
							 | 
						||
| 
								 | 
							
								└── decorators
							 | 
						||
| 
								 | 
							
								└── hooks
							 | 
						||
| 
								 | 
							
								└── your services
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								In this way, you will always have access to all of the properties declared in
							 | 
						||
| 
								 | 
							
								the current scope.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								As discussed previously, Fastify offers a solid encapsulation model, to help you
							 | 
						||
| 
								 | 
							
								build your application as single and independent services. If you want to
							 | 
						||
| 
								 | 
							
								register a plugin only for a subset of routes, you just have to replicate the
							 | 
						||
| 
								 | 
							
								above structure.
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								└── plugins (from the Fastify ecosystem)
							 | 
						||
| 
								 | 
							
								└── your plugins (your custom plugins)
							 | 
						||
| 
								 | 
							
								└── decorators
							 | 
						||
| 
								 | 
							
								└── hooks
							 | 
						||
| 
								 | 
							
								└── your services
							 | 
						||
| 
								 | 
							
								    │
							 | 
						||
| 
								 | 
							
								    └──  service A
							 | 
						||
| 
								 | 
							
								    │     └── plugins (from the Fastify ecosystem)
							 | 
						||
| 
								 | 
							
								    │     └── your plugins (your custom plugins)
							 | 
						||
| 
								 | 
							
								    │     └── decorators
							 | 
						||
| 
								 | 
							
								    │     └── hooks
							 | 
						||
| 
								 | 
							
								    │     └── your services
							 | 
						||
| 
								 | 
							
								    │
							 | 
						||
| 
								 | 
							
								    └──  service B
							 | 
						||
| 
								 | 
							
								          └── plugins (from the Fastify ecosystem)
							 | 
						||
| 
								 | 
							
								          └── your plugins (your custom plugins)
							 | 
						||
| 
								 | 
							
								          └── decorators
							 | 
						||
| 
								 | 
							
								          └── hooks
							 | 
						||
| 
								 | 
							
								          └── your services
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Validate your data
							 | 
						||
| 
								 | 
							
								<a id="validate-data"></a>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Data validation is extremely important and a core concept of the framework.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								To validate incoming requests, Fastify uses [JSON
							 | 
						||
| 
								 | 
							
								Schema](https://json-schema.org/).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(JTD schemas are loosely supported, but `jsonShorthand` must be disabled first)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Let's look at an example demonstrating validation for routes:
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const opts = {
							 | 
						||
| 
								 | 
							
								  schema: {
							 | 
						||
| 
								 | 
							
								    body: {
							 | 
						||
| 
								 | 
							
								      type: 'object',
							 | 
						||
| 
								 | 
							
								      properties: {
							 | 
						||
| 
								 | 
							
								        someKey: { type: 'string' },
							 | 
						||
| 
								 | 
							
								        someOtherKey: { type: 'number' }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.post('/', opts, async (request, reply) => {
							 | 
						||
| 
								 | 
							
								  return { hello: 'world' }
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								This example shows how to pass an options object to the route, which accepts a
							 | 
						||
| 
								 | 
							
								`schema` key that contains all of the schemas for route, `body`, `querystring`,
							 | 
						||
| 
								 | 
							
								`params`, and `headers`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Read [Validation and
							 | 
						||
| 
								 | 
							
								Serialization](../Reference/Validation-and-Serialization.md) to learn more.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Serialize your data
							 | 
						||
| 
								 | 
							
								<a id="serialize-data"></a>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Fastify has first class support for JSON. It is extremely optimized to parse
							 | 
						||
| 
								 | 
							
								JSON bodies and to serialize JSON output.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								To speed up JSON serialization (yes, it is slow!) use the `response` key of the
							 | 
						||
| 
								 | 
							
								schema option as shown in the following example:
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const opts = {
							 | 
						||
| 
								 | 
							
								  schema: {
							 | 
						||
| 
								 | 
							
								    response: {
							 | 
						||
| 
								 | 
							
								      200: {
							 | 
						||
| 
								 | 
							
								        type: 'object',
							 | 
						||
| 
								 | 
							
								        properties: {
							 | 
						||
| 
								 | 
							
								          hello: { type: 'string' }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.get('/', opts, async (request, reply) => {
							 | 
						||
| 
								 | 
							
								  return { hello: 'world' }
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								By specifying a schema as shown, you can speed up serialization by a factor of
							 | 
						||
| 
								 | 
							
								2-3. This also helps to protect against leakage of potentially sensitive data,
							 | 
						||
| 
								 | 
							
								since Fastify will serialize only the data present in the response schema. Read
							 | 
						||
| 
								 | 
							
								[Validation and Serialization](../Reference/Validation-and-Serialization.md) to
							 | 
						||
| 
								 | 
							
								learn more.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Parsing request payloads
							 | 
						||
| 
								 | 
							
								<a id="request-payload"></a>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Fastify parses `'application/json'` and `'text/plain'` request payloads
							 | 
						||
| 
								 | 
							
								natively, with the result accessible from the [Fastify
							 | 
						||
| 
								 | 
							
								request](../Reference/Request.md) object at `request.body`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The following example returns the parsed body of a request back to the client:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const opts = {}
							 | 
						||
| 
								 | 
							
								fastify.post('/', opts, async (request, reply) => {
							 | 
						||
| 
								 | 
							
								  return request.body
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Read [Content-Type Parser](../Reference/ContentTypeParser.md) to learn more
							 | 
						||
| 
								 | 
							
								about Fastify's default parsing functionality and how to support other content
							 | 
						||
| 
								 | 
							
								types.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Extend your server
							 | 
						||
| 
								 | 
							
								<a id="extend-server"></a>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Fastify is built to be extremely extensible and minimal, we believe that a
							 | 
						||
| 
								 | 
							
								bare-bones framework is all that is necessary to make great applications
							 | 
						||
| 
								 | 
							
								possible.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In other words, Fastify is not a "batteries included" framework, and relies on
							 | 
						||
| 
								 | 
							
								an amazing [ecosystem](./Ecosystem.md)!
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Test your server
							 | 
						||
| 
								 | 
							
								<a id="test-server"></a>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Fastify does not offer a testing framework, but we do recommend a way to write
							 | 
						||
| 
								 | 
							
								your tests that uses the features and architecture of Fastify.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Read the [testing](./Testing.md) documentation to learn more!
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Run your server from CLI
							 | 
						||
| 
								 | 
							
								<a id="cli"></a>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Fastify also has CLI integration thanks to
							 | 
						||
| 
								 | 
							
								[fastify-cli](https://github.com/fastify/fastify-cli).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								First, install `fastify-cli`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								npm i fastify-cli
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								You can also install it globally with `-g`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Then, add the following lines to `package.json`:
							 | 
						||
| 
								 | 
							
								```json
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  "scripts": {
							 | 
						||
| 
								 | 
							
								    "start": "fastify start server.js"
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								And create your server file(s):
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								// server.js
							 | 
						||
| 
								 | 
							
								'use strict'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = async function (fastify, opts) {
							 | 
						||
| 
								 | 
							
								  fastify.get('/', async (request, reply) => {
							 | 
						||
| 
								 | 
							
								    return { hello: 'world' }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Then run your server with:
							 | 
						||
| 
								 | 
							
								```bash
							 | 
						||
| 
								 | 
							
								npm start
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Slides and Videos
							 | 
						||
| 
								 | 
							
								<a id="slides"></a>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- Slides
							 | 
						||
| 
								 | 
							
								  - [Take your HTTP server to ludicrous
							 | 
						||
| 
								 | 
							
								    speed](https://mcollina.github.io/take-your-http-server-to-ludicrous-speed)
							 | 
						||
| 
								 | 
							
								    by [@mcollina](https://github.com/mcollina)
							 | 
						||
| 
								 | 
							
								  - [What if I told you that HTTP can be
							 | 
						||
| 
								 | 
							
								    fast](https://delvedor.github.io/What-if-I-told-you-that-HTTP-can-be-fast)
							 | 
						||
| 
								 | 
							
								    by [@delvedor](https://github.com/delvedor)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- Videos
							 | 
						||
| 
								 | 
							
								  - [Take your HTTP server to ludicrous
							 | 
						||
| 
								 | 
							
								    speed](https://www.youtube.com/watch?v=5z46jJZNe8k) by
							 | 
						||
| 
								 | 
							
								    [@mcollina](https://github.com/mcollina)
							 | 
						||
| 
								 | 
							
								  - [What if I told you that HTTP can be
							 | 
						||
| 
								 | 
							
								    fast](https://www.webexpo.net/prague2017/talk/what-if-i-told-you-that-http-can-be-fast/)
							 | 
						||
| 
								 | 
							
								    by [@delvedor](https://github.com/delvedor)
							 |