В этом руководстве будут рассмотрены типичные варианты использования, с которыми вы столкнетесь при написании конечных точек RESTful API для чтения и записи в экземпляр базы данных Firebase.
Особое внимание будет уделено красивому асинхронному коду, в котором используется функция async/await
в Node.js (доступна в версии 7.6 и выше).
(Не стесняйтесь сладко улыбаться, когда вы машете на прощание, чтобы позвонить в ад 👋)
Предпосылки
Я предполагаю, что у вас уже есть приложение Node.js, настроенное с помощью Firebase Admin SDK. Если нет, то ознакомьтесь с официальным руководством по установке.
Запись данных
Прежде всего, давайте создадим пример POST
конечной точки, которая будет сохранять слова в нашем экземпляре базы данных Firebase:
Это очень простая конечная точка, которая принимает значения userId
и word
, а затем сохраняет данное слово в коллекцию words
. Достаточно просто.
Но что-то не так. Нам не хватает обработки ошибок! В приведенном выше примере мы возвращаем код состояния 201
(означающий, что ресурс был создан), даже если слово не было должным образом сохранено в нашем экземпляре базы данных Firebase.
Итак, давайте добавим обработку ошибок:
Теперь, когда конечная точка возвращает точные коды состояния, клиент может отображать соответствующее сообщение пользователю. Например, «Слово успешно сохранено». Или «Невозможно сохранить слово, нажмите здесь, чтобы повторить попытку».
Примечание: если какой-то синтаксис ES2015 + кажется вам незнакомым, ознакомьтесь с Руководством по ES2015 Babel.
Чтение данных
Хорошо, теперь, когда мы записали некоторые данные в нашу базу данных Firebase, давайте попробуем прочитать их.
Во-первых, давайте посмотрим, как выглядит GET
конечная точка, используя исходный метод на основе обещаний:
Опять же, достаточно просто. Теперь сравним его с async/await
версией того же кода:
Обратите внимание на ключевое слово async
, добавленное перед параметрами функции (req, res)
, и ключевое слово await
, которое теперь предшествует оператору db.ref()
.
Метод db.ref()
возвращает обещание, что означает, что мы можем использовать ключевое слово await
, чтобы «приостановить» выполнение скрипта. (Ключевое слово await
может использоваться с любым обещанием).
Последний res.send()
метод будет запущен только после выполнения db.ref()
обещания.
Это все хорошо, но истинная красота async/await
становится очевидной, когда вам нужно объединить несколько асинхронных запросов в цепочку.
Допустим, вам нужно было последовательно запустить ряд асинхронных функций:
Не очень. Это также известно как «пирамида гибели» (и мы еще даже не добавили обработчики ошибок).
Теперь взгляните на приведенный выше фрагмент, переписанный для использования async/await
:
Нет больше пирамиды гибели! Более того, все операторы await
можно заключить в один блок try/catch
для обработки любых ошибок:
Параллельные запросы async / await
Как насчет случаев, когда вам нужно одновременно получить несколько записей из базы данных Firebase?
Легкий. Просто используйте метод Promise.all()
для параллельного выполнения запросов к базе данных Firebase:
Еще кое-что
При создании конечной точки для возврата данных, полученных из экземпляра базы данных Firebase, будьте осторожны, чтобы просто не вернуть весь snapshot.val()
. Это может вызвать проблемы с синтаксическим анализом JSON на клиенте.
Например, предположим, что у вашего клиента есть следующий код:
snapshot.val()
, возвращаемый Firebase, может быть либо объектом JSON, либо null
, если запись не существует. Если возвращается null
, response.json()
в приведенном выше фрагменте выдаст ошибку, поскольку пытается проанализировать тип, не являющийся объектом.
Чтобы защитить себя от этого, вы можете использовать Object.assign()
, чтобы всегда возвращать объект клиенту:
Спасибо за прочтение!
Хотите увидеть реальный проект, созданный на основе Firebase и Node.js? Попробуйте Vocabify, конструктор словарного запаса, который поможет вам запоминать слова, с которыми вы сталкиваетесь.