Что такое 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

Спасибо за чтение!
Поделиться с друзьями
-->

Комментарии (14)


  1. Suvitruf
    29.08.2016 17:46
    +1

    Horizon — это продукт содержащий в себе NoSQL базу данных RethinkDB
    Ну, не совсем так. Он работает с RethinkDB, да, но не завязан на него. Более того, Слава в своё время говорил, что в будущем планируется сделать поддержку других баз. Главное, чтобы они поддерживали функционал подписок/пушей.

    Умеет рассылать по WebSoket уведомления о изменениях (рассылку можно фильтровать сразу на уровне БД)
    Они всё больше развивают этот функционал, но и там до сих пор есть свои проблемы.

    Умеет масштабироваться
    В их слаке наблюдаю периодически, как люди жалуются на проблемы при большой нагрузке. Вроде как из-за необходимости обращаться к праймари реплике. Но, возможно, люди просто репликацию плохо настроили.

    Умеет Join-ы
    Только они довольно медленные)

    Мощный язык запросов
    И прекрасные драйвера, кстати. Под node.js работать одно удовольствие даже без ORM. В Java, правда, есть свои проблемы: часто приходится писать много лишнего кода (к примеру, заворачивать объекты в HashMap'ы для передачи в запросы), но самая большая проблема — нет асинхронности. На данный момент мы это решили за счёт использование пула соединений. Но по плану у них на осень переписывание Java драйвера, чтоб он умел в асинхронность.

    Имеет встроенный web-интерфейс для мониторинга и быстрого доступа к данным
    Довольно удобная штуку. Плюс многие системные настройки прям там запросами можно изменить (авторизацию, репликацию и т.п.).

    У меня лично был доступ к Horizon на этапе закрытого тестирования. Тогда довольно перспективным показалось. Предполагаю, что в релизе они многие недочёты подправили.


    1. jMas
      29.08.2016 17:54

      Спасибо, я только начал пользоваться Horizen / RethinkDB, поэтому мне пока сложно определить границы и все возможности продукта. Но определенно буду использовать для быстрого прототипирования или мелких апп.
      Скажите, у вас ведь есть уже что то в продакшине, какую нагрузку держит? Всем довольны или потом пожалели что взяли? Думаю, читателям и мне интересно будет узнать о реальных проектах с использованием этой БД.


      1. Suvitruf
        29.08.2016 18:12

        Всем довольны или потом пожалели что взяли?
        О RethinkDB не пожалели. Раньше, к примеру, мы использовали Riak, вот о нём пожалели. Сейчас, правда, используем всё ещё Riak, но только как бэкенд для ejabberd.

        Скажите, у вас ведь есть уже что то в продакшине, какую нагрузку держит?
        RethinkDB используем для онлайн игры. Все игровые данные в нём храним. У нас пока только софтланч, поэтому особо больших нагрузок нет. Но десятки тысяч чтений/записей оно спокойно держит. Не знаю, много это или нет. Да и цифры то эти ни о чём в целом не говорят. Всё зависит от того, как вы приготовите запросы: будете выполнять их на клиенте (при этом тягая данные из бд на клиент) или же будете правильно составлять ReQL запросы, чтоб они выполнялись на сервере и возвращали только ответ.


        1. jMas
          29.08.2016 18:18

          Да, цифры действительно не о чем не говорят. Необходимы параметры железа и хотя бы сравнительные тесты. Но все равно спасибо за ответ.
          Посмотрел на сайте RethinkDB, в блоге есть недавний отчет о тестировании производительности, возможно из него удастся понятно что к чему.


          1. Suvitruf
            29.08.2016 18:46

            Вот только версия RethinkDB в тесте используется годичной давности =/


  1. markhor
    29.08.2016 18:58

    Интересно, а как защищаться от DDOS-а, заставляя базу данных делать кучу медленных тяжелых запросов? Удобный API для доступа по сути уже есть…


    1. jMas
      29.08.2016 19:24

      Хороший вопрос. Поискав Github issues и Api RethinkDB — ничего про защиту от DDoS, к сожалению, не нашел. Было одно упоминание, мол неплохо было бы добавить в правила rateLimit, то есть максимальное количество данного типа запросов которое база будет обрабатывать за единицу времени, но видимо осталось на уровне «хотелки».


  1. comerc
    29.08.2016 23:01

    Как же вовремя, спасибо! Вчера поставил, разбираюсь.


  1. comerc
    29.08.2016 23:07

    1. jMas
      30.08.2016 00:32
      +1

      Статья прошлогодняя и комментарий тоже, сейчас уже актуальна новая версия RethinkDB, поэтому советую взглянуть на бенчмарки (и тут развернуто). Конечно я не стараюсь вас обнадежить — необходимо с умом подходить к выбору БД. Но есть комментарий разработчиков, что БД в версии 2.1.5 линейно масштабируется на Amazon EC2. Так что кто знает. Можете рассказать о планах применения RethinkDB, и возможно Suvitruf сможет вам ответить — подходит или нет, исходя из своего опыта эксплуатации этой БД.


      1. comerc
        30.08.2016 00:39

        Функционал Хабра, примерно: посты, комменты, лайки, уведомления, личка.


        1. jMas
          30.08.2016 01:06
          +1

          Я бы посоветовал погуглить на тему «RethinkDB benchmark», «RethinkDB perfomance», «RethinkDB vs MongoDB perfomance», заглянуть сюда.
          Из нескольких источников, где тестировалась версия 2.0.X было видно, что производительность уступает MongoDB и на порядки, но сейчас актуальна версия 2.3.5. Какие улучшения производительности были достигнуты за это время — не известно.
          Можно не гадать, а запилить небольшой тест для чтения и инсертов, аналогичный этому и потом сделать пост на эту тему. Было бы здорово.
          Ну и стоит понимать, что иногда в угоду специфичным фичам (например возможности подписаться на изменения или важна простота старта, или язык запросов единственный понятный вам) можно пожертвовать производительностью, а иногда проект никогда не вырастит до огромной посещаемости, поэтому возможно оно и не понадобится. Каждый случай уникален в каком то смысле.


  1. PaulMaly
    31.08.2016 20:07

    Тоже приглядываюсь к Horizon, но пока не понятно в чем его преимущества перед тем же ParseServer, который считай до недавнего момента был вообще проприетарным. Плюс считай под нагрузками проверен более или менее. Админка и SDK под кучу библиотек в комплекте тоже.

    Может есть кто юзал и то и другое?


    1. jMas
      02.09.2016 17:16

      Cтек более монолитный (база и веб-сервер) от одной команды. Умеет нотификейшены сразу из базы в веб-сокет (сделано на уровне базы). Да и оно больше для SPA и Mobile HTML5 приложений, чем как бэкэнд для Native. Если для Native, то RethinkDB выглядит более логичным, Horizon тут будет лишним.
      Но честно, не готов советовать. Вверху есть ребята которые работают с RethinkDB, можете поспрашивать.