Декораторы в Fastify — это мощный механизм, позволяющий расширять функциональность приложения с минимумом затрат. Технически, декораторы — это функции, которые добавляют дополнительную логику к маршрутам или к самому приложению. Они нужны для удобства и эффективности работы с приложением, а также для упрощения процесса разработки.
Декораторов в Fastify очень много. В этом уроке мы разберем только некоторые наиболее популярные из них. Полученные знания будут применимы и к любым другим декораторам.
Decorate
Одним из наиболее часто используемых декораторов в Fastify является decorate. Он используется для добавления новых методов и свойств к объекту приложения. Разберем пример:
import fastify from 'fastify'
const app = fastify()
// добавляем новый метод к объекту request
app.decorate('getData', () => {
return { message: 'Hello World' }
})
// использование нового метода
app.get('/', (req, res) => {
res.send(app.getData())
})
app.listen({ port: 3000 }, () => {
console.log('Server is running on port 3000')
})
В примере выше мы добавили в свойство getData
функцию, которая возвращает объект { message: 'Hello World' }
. Теперь этот метод можно вызывать в любых обработчиках.
Decorate Request/Reply
Декораторы decorateRequest()
и decorateReply()
позволяют модифицировать объекты запрос и ответа соответственно. Они позволяют добавить свойства или методы в эти объекты.
import fastify from 'fastify'
const app = fastify()
app.decorateRequest('util', function () {
// какая-то логика
// объект this — это request
})
app.decorateReply('render', function () {
// какая-то логика
// объект this — response
})
app.get('/', (req, res) => {
req.util() // вызов метода из декоратора для объекта request
res.render() // вызом метода из декоратора для объекта response
})
В примере выше мы создали два метода util()
для объекта request
и render()
для объекта response
. Обратите внимание, что в декораторах используется function
. Это нужно, чтобы сохранить контекст объектов, для которых мы создаем методы.
Такой подход позволяет создать обобщенную логику, в которой нужны эти объекты.
Hooks
Еще одним полезным декоратором являются хуки. Они позволяют добавить перехватчики (hooks) к маршрутам или к приложению для выполнения дополнительных действий перед или после выполнения действия. Разберем пример:
import fastify from 'fastify'
const app = fastify()
// добавляем перехватчик перед обработкой запроса
app.addHook('preHandler', (req, res, next) => {
console.log(`Запрос выполнен в ${new Date()}`)
next()
})
app.get('/', (req, res) => {
res.send({ message: 'Hello World' })
})
app.listen(3000, () => {
console.log('Server is running on port 3000')
})
Выше, с помощью хука preHandler
мы добавили функцию, которая ведет лог времени запроса. Теперь, при каждом запросе, в лог будет выводиться запись вида "Запрос выполнен в 2024-05-03T11:38:20.946Z". Хук работает по схожему принципу, как мидлвары.
В Fastify есть множество хуков на разные действия. Глобально их можно разделить на две группы:
- Хуки запросов — они срабатывают во время события запроса или ответа
- Хуки приложения — эти хуки срабатывают во время каких-то событий самого приложения, например, когда добавляется обработчик маршрута
Хуки запросов
Мы уже разобрали один такой хук. Ниже список таких хуков и примеры использования:
onRequest
— выполняется перед обработкой запроса
app.addHook('onRequest', (req, res, done) => {
console.log(`Запрос выполнен в ${new Date()}`)
done()
})
preParsing
— выполняется до того, как тело запроса будет прочитано
app.addHook('preParsing', (req, res, done) => {
console.log('Parsing request body')
done()
})
preValidation
— выполняется перед валидацией запроса
app.addHook('preValidation', (req, res, done) => {
console.log('Validating request')
done()
})
preHandler
— выполняется перед обработкой маршрута
app.addHook('preHandler', (req, res, done) => {
console.log('Executing preHandler hook')
done()
})
preSerialization
— выполняется перед формированием ответа
app.addHook('preSerialization', (req, res, payload, done) => {
console.log('Preparing response for serialization')
done(null, { customResponse: payload })
})
Эти хуки позволяют выполнить дополнительные действия на различных этапах обработки запросов, что может быть полезно для логирования, аутентификации, валидации данных и других задач.
Хуки приложения
Ниже представлены некоторые хуки приложения:
onRoute
— выполняется при добавлении обработчика маршрута
app.addHook('onRoute', (routeOptions) => {
console.log('Добавлен маршрут:', routeOptions.path)
})
app.get('/', (req, res) => { // будет вызвана фукнция, которую мы добавили в хук onRoute
res.send({ message: 'Hello World' })
})
onClose
— выполняется перед закрытием приложения
app.addHook('onClose', (instance, done) => {
console.log('Closing application')
done()
})
onReady
— выполняется после завершения всех регистраций маршрутов, плагинов и готовности приложения к работе
app.addHook('onReady', () => {
console.log('Application is ready')
})
onError
— выполняется при возникновении ошибки
app.addHook('onError', (error, instance) => {
console.error('Error during hook execution:', error.message)
})
Эти хуки приложения позволяют выполнять дополнительные действия на различных этапах жизненного цикла приложения Fastify, такие, как управление маршрутами, регистрация плагинов, закрытие приложения и обработка ошибок.
Рассмотренные выше примеры демонстрируют базовое использование декораторов в fastify. Они помогают сделать код более чистым, модульным и удобным для разработки и поддержки. Мы разобрали только часть декораторов. Полный список вы можете посмотреть в документации. Но уже рассмотренных в уроке может хватить для большинства задач.
Дополнительные материалы
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.