Что такое Horizon?
Horizon — это продукт содержащий в себе NoSQL базу данных RethinkDB, консольную утилиту horizon
(hz
), авторизацию и ACL, клиентскую JS библиотеку horizon.js
для работы с БД на клиенте.
Другими словами: Horizon — это тонкий бэкэнд: БД и правила доступа пользователей к базе на уровне запросов.
Что внутри?
RethinkDB
Удобная NoSQL БД, которая умеет рассылать уведомления о изменениях в коллекциях. На хабре уже писали о ней: “Строим real-time веб-приложения с RethinkDB”.
Вкратце о NoSQL RethinkDB:
- Умеет рассылать по WebSoket уведомления о изменениях (рассылку можно фильтровать сразу на уровне БД)
- Умеет масштабироваться
- Умеет Join-ы
- Мощный язык запросов
- Имеет встроенный web-интерфейс для мониторинга и быстрого доступа к данным
Консольная утилита
После уcтановки Horizon сразу становится доступной утилита horizon
(или hz
). С ее помощью можно:
- Инициализировать новое Horizon-приложение
- Запустить веб-сервер для Horizon-приложения
- Сгенерировать SSL сертификат для разработки
- Сгенерировать токен для юзера
- Выгрузить или вгрузить схему для RethinkDB
- Мигрировать со старой на новую версию
ACL (Access Control List)
В Horizon из коробки поддерживает OAuth авторизацию (стандарт JSON Web Tokens), доступны провайдеры Facebook, Github, Google, Slack, Twitch, Twitter, Auth0 (последний позволяет значительно расширить этот список).
Существует несколько групп пользователей по-умолчанию:
- Не авторизованный
- Анонимный
- Авторизованный
- Админ
Для каждой группы можно настроить белый список запросов на чтение/запись для каждой коллекции. В боевом режиме каждый запрос к базе будет сверяться с этим списком, если одно из правил будет правильным — запрос выполнится. Правило представляет собой комбинацию обычного запроса к базе данных и функций-подстановок.
Примеры ACL-правил для запросов
Не авторизованные пользователи, чтение профилей пользователя:
[groups.unauthenticated.rules.read_profile]
template = "collection('users').anyRead()"
Чтение профиля авторизованным пользователем:
[groups.authenticated.rules.read]
template = "collection('posts').anyRead()"
Нужно обратить внимание, что здесь используются функция-подстановка anyRead()
, означающая возможность читать любые записи. Функция не используется в реальных запросах.
Обновление информации о профиле пользователя:
[groups.authenticated.rules.upadate_profile]
template = "collection('users').upadate({id: userId(), username: any()})"
Здесь используются две функции-подстановки userId()
и any()
. userId()
— подствляет ID текущего авторизованного пользователя. any()
— подставляет любые данные.
Как это работает в теории? Например вы хотите сделать запрос к базе данных: update({id: 1, username: ‘Bob’})
, на стороне БД происходит проверка всех правил, сверяются ключи. На входе БД видит id=1
, по правилу БД строит объект с ключем id=userId()
, пытается сравнить 1
и userId()
. Такая же операция происходит и с ключем username
: проверяется “Bob”
и any()
. Во втором случае, функция any()
позволяет пропустить любые данные — просто здесь мы проверили, что ключ username
присутствует во входных данных. Если все хорошо, запрос успешно выполнится.
horizon.js
После запуска веб-сервера приложения вам станет доступна клиентская библиотека /horizon/horizon.js
. Она позволяет делать следующее:
- Развернуть WebSoket-подключение к базе RethinkDB
- Создавать запросы к БД и подписываться на изменения коллекции или списка коллекций
- Произвести OAuth авторизацию и получить текущего пользователя
Взглянуть на полный список методов можно здесь: horizon.io/api/horizon, horizon.io/api/collection.
Как это работает?
Есть несколько официальных примеров, демонстрирующих работу Horizon на примере чата (React, Vue, все примеры).
Но приведенные примеры не демонстрируют авторизацию и настройку прав доступа к записям, поэтому я собрал собственный пример Social Feed на Vanilla.
Как развернуть?
Разворачивается все просто:
npm install -g horizon
hz init hz-app
cd hz-app
hz serve --dev
Все нюансы установки вы можете найти здесь: horizon.io/install и здесь: horizon.io/docs/getting-started.
Для кого?
Этот продукт определенно понравится тем, кто хорошо знает JavaScript и не хочет тратить время на бэкэнд. Horizon идеально подойдет для любителей делать прототипы.
Если говорить о сферах применения, то Horizon возможно будет интересен:
- Разработчикам мобильных приложений / игр
- Разработчикам PhoneGap приложений
- Для создания интерактивных SPA-приложений (чаты, форумы)
Выводы
Плюсы
- Очень просто установить и начать работать
- Простая и понятная документация
- Понятный API
- Подписка на обновления коллекций / агрегированных запросов
- WebSoket
- Продукт динамично развивается
Минусы
- Нет успешных примеров из жизни
- Достаточно молод, не так много информации и решенных проблем
- Есть вопросы к поддержке старыми браузерами
В остатке
Неплохой продукт для прототипирования и быстрого старта. Удобный API доступа к базе. Есть возможность настроить доступ к записям. Много внимания уделено HTTPS и защите, масштабированию. Все же не ясно как Horizon работает в реальной жизни, нет успешных примеров. Однако видно, что проект успел собрать много звезд и положительных отзывов. Может стоит пробовать в продакшине?
» Веб-сайт Horizon: horizon.io
» Github: github.com/rethinkdb/horizon
» Видео о Horizon на английском: www.youtube.com/watch?v=ajb_IeXcVw4
Спасибо за чтение!
Автор: jMas