Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Совсем недавно начал изучать фреймворк Fastify, который почему-то не особо популярен в русскоязычном сегменте интернета. Для хранения переменных конфигурации я всегда использовал файл .env
. Для чтения файла .env
на Express я привык использовать всем известную библиотеку dotenv, то врем как в экосистеме Fastify есть своя библиотека - @fastify-env.
Я в обратился к документации... и ничего не понял. Я попробовал реализовать то, что там указано, но у меня ничего не вышло. Туториал на youtube от какого-то индуса так же не помог (хотя у индийского программиста всё получилось)...
Сославшись на позднее время суток и усталость мозга, я сдался и начал искать какое-нибудь готовое решение в интернете, и оно нашлось достаточно быстро. Выяснилось, что я не один сталкиваюсь с такой проблемой и это частая сложность у программистов пришедших в Fastify после Express.
Итак, ниже пойдёт перевод этой статьи от 27.07.2021 г. (обновлено 18.02.2022 г.). Перед прочтением статьи рекомендую потратить 5-10 минут времени на чтение ооочень короткой официальной документации библиотеки @fastify-env.
Проблема: как мне получить доступ к моему файлу .env в Fastify?
Исходя из опыта работы в Express, я привык использовать модуль dotenv для чтения переменных конфигурации, таких как имя пользователя и пароль для базы данных, secret для jsonwebtokens и другие, из моего файла .env
.
Подключившись к экосистеме плагинов fastify, я установил fastify-env и попытался использовать его для загрузки содержимого моего файла .env
. Первоначальная проблема, с которой я столкнулся, заключалась в том, что документация для доступа к переменным .env с использованием fastify-env казалась немного скудной, и я не смог найти ни одного хорошего руководства.
Попробовав несколько разных подходов с помощью fastify-env и не сумев прочитать переменные из .env
, я сдался и установил dotenv. Этот подход сработал, и я смог успешно подключить fastify к базе данных MongoDB. Однако огромным недостатком использования dotenv с fastify является то, что переменные .env недоступны в экземпляре fastify, поэтому доступ к ним из модулей, скрытых в структуре каталогов, быстро становится головной болью.
Я планировал использовать jsonwebtokens в своем приложении для аутентификации пользователей на серверной части. Чтобы их проверить, мне нужно сохранить 'секрет' на сервере и получить к нему доступ из разных модулей, которые включают логику проверки. Хотя решение dotenv работало достаточно хорошо для учетных данных базы данных, оно было слишком громоздким для доступа к 'секрету'. Итак, я снова попробовал fastify-env.
Решение или ключевые моменты, которые я пропустил
Используя fastify в первый раз, я столкнулся сразу с несколькими новыми концепциями и пропустил несколько важных элементов в своих первых попытках использовать fastify-env. Надеюсь, следующее краткое изложение моего опыта поможет другим новичкам в fastify-env сэкономить время и усилия.
Переменные файла .env должны быть включены в схему (shema)
Первое, что я пропустил при первой попытке использования fastify-env, это то, что переменные в файле .env должны быть включены в схему, используемую fastify-env, иначе они будут недоступны. Следующие фрагменты кода дают пример того, как это работает:
.env
USERNAME=databaseUsername
PASSWORD=doubleSecretDatabasePassword
server.js
const schema = {
type: 'object',
required: ['PASSWORD', 'USERNAME'],
properties: {
PASSWORD: {
type: 'string'
},
USERNAME: {
type: 'string'
}
}
}
Установите для ключа "data" значение "process.env"
Второй ключевой момент, который я пропустил, заключался в том, что для ключа данных в объекте options необходимо установить значение "process.env" для чтения файла .env. Недостаточно просто установить для ключа dotenv значение true. Следующий фрагмент кода показывает, как правильно установить оба ключа.
server.js
const options = {
dotenv: true,
data: process.env
}
Функция ready() работает не так как я думал в начале.
Третья и последняя вещь, которую я не понял при первоначальной попытке использовать fastify-env, заключалась в том, что ожидание fastify.ready()
перед fastify.listen()
не загружает все плагины по порядку. Однако ожидание fastify.after()
в строке после fastify.register()
гарантирует, что переменные .env будут определены после fastify.after()
, как показано в следующем фрагменте кода.
server.js
fastify.register(fastifyEnv, options)
await fastify.after()
// Теперь переменные .env определены
Соберём всё это вместе!
Следующий фрагмент кода показывает все мое решение с использованием fastify-env для настройки URL-адреса подключения для аутентификации в базе данных MongoDB с использованием значений имени пользователя и пароля, заданных в файле .env.
server.js
// Fastify
const fastify = require('fastify')({
logger: true
})
const fastifyEnv = require('fastify-env')
const schema = {
type: 'object',
required: ['DB_PASSWORD', 'DB_USERNAME'],
properties: {
DB_PASSWORD: {
type: 'string'
},
DB_USERNAME: {
type: 'string'
}
}
}
const options = {
confKey: 'config',
schema,
dotenv: true,
data: process.env
}
const initialize = async () => {
fastify.register(fastifyEnv, options)
await fastify.after()
// Database
// Connection URL
const username = encodeURIComponent(fastify.config.DB_USERNAME)
const password = encodeURIComponent(fastify.config.DB_PASSWORD)
const dbName = 'databaseName'
const url = `mongodb://${username}:${password}@localhost:27017/${dbName}`
fastify.register(require('./database-connector'), {
url,
useUnifiedTopology: true
})
}
initialize()
// Запуск сервера
(async () => {
try {
await fastify.ready()
await fastify.listen(process.env.PORT)
} catch (error) {
fastify.log.error(error)
process.exit(1)
}
})()
Я надеюсь, что другие программисты найдут это полезным. Кроме того, если у кого-либо из экспертов fastify-env есть предложения по улучшению этого подхода, пожалуйста, не стесняйтесь оставлять их в комментариях. Спасибо за чтение и удачного кодирования!
Пожалуйста, обратите внимание: "database-connection" - это плагин fastify, который я написал для использования официального драйвера MongoDB версии 4.x, потому что в то время fastify-mongodb использовал драйвер 3.x под капотом. С тех пор fastify-mongodb был обновлен для использования драйвера 4.x, поэтому, вероятно, используйте его в своем проекте.
На этом всё! Я так же как и автор статьи надеюсь, что начинающим программистам (коим и я являюсь) эта статья сэкономит время и нервы, ибо я сам изрядно намучился пытаясь самостоятельно всё это дело настроить.
P.S. это моя первая статья на Хабре, буду рад комментариям и обратной связи по содержанию статьи.