Skip to content

Instantly share code, notes, and snippets.

@dmitry-vsl
Created September 11, 2015 22:01
Show Gist options
  • Save dmitry-vsl/24a621cd7a02446c06e0 to your computer and use it in GitHub Desktop.
Save dmitry-vsl/24a621cd7a02446c06e0 to your computer and use it in GitHub Desktop.
Архитектура средненагруженных single page application приложений в 2016 году

Клиент

На клиенте используем стэк фейсбука:

  • React.js. Один из самых популярных javascript фреймворков, интегрированный с остальными частями facebook-стэка.
  • GraphQL. Протокол для доступа к данным, который адресует недостатки REST API.
  • Relay. Клиентская библиотека для удобной работы с grapqhl-сервером.
  • Flow type. Типизированное надмножество javascript, умеет выводить анонимные типы из graphql-запросов используя grapqhl-схему.

Сервер

На сервере используем:

  • [PostgreSQL][http://www.postgresql.org/]. Лучшая open source СУБД.
  • node.js. Серверная платформа, которая может рендерить react-компоненты на сервере, позволяя создавать изоморфные приложения. Удобна для создания асинхронных webscoket и server sent events серверов.
  • GraphQL reference implementation. Имплементация graphql для javascript.

Архитектура сервера

В приложении есть три вида node.js серверов (один сервер может выполнять сразу три роли).

  • GraphQL endpoint - отвечает на graphql запросы
  • http endpoint - отвечает на http запросы к сайту (за исключением статики) и выдает html, сгенерированный на сервере реактом
  • server sent events endpoint - оповещает клиентов об изменениях данных, произошедшых на сервере

Слой доступа к данным

GraphQL reference implementation умеет парсить и проверять запросы на корректность, а также преобразовывать запросы в набор вызовов функций resolve, которые должны получить данные для каждой вершины в graphql запросе. Функции resolve мы реализуем следующим образом: для каждой вершины в graphql схеме создадим view в postgresql базе, которое выдает необходимые данные. Наша имплементация функции resolve просто делает запрос к view. Плюсы такого решения:

  • Высокодекларативный код
  • Код view статически типизирован
  • Упрощается коммуникация с доменными экспертами, которые знают SQL но не умеют программировать на javascript
  • Код привязывается к персистентным данным, а не к javascript - технологии user interface. Код не устаревает при выходе очередной смене UI технологии
  • Улучшенная security. Веб-сервер не имеет доступа напрямую к таблицам, он имеет доступ только к view, которые являются API базы данных (аналогично "геттерам" в ООП)
  • Код замкнут относительно композиции. Можно из view строить более сложные view. Если мы храним запросы в javascipt коде в виде строк, то теряется возможность композиции запросов.
  • Высокая производительность. При запросах все предикаты применяются в базе данных, сокращая количество IO. Решается N + 1 seleсt problem

Модификация данных

На каждый возможный mutation содаем одноименную хранимую процедуру в postgresql. Плюсы такого решения:

  • независимость от javascript
  • security. Веб сервер не может напрямую писать в таблицы, только вызывать хранимые процедуры (аналогично "сеттерам" в ООП)
  • не надо беспокоиться об открывании/коммите/откате транзакции. На node.js это сложно реализовать в виду асинхронности API и отсутствия исключений. Кроме того, не надо беспокоиться о prepared statement

Server sent events

Для реализации SSE используем postgresql logical decoding. К основному или hot standby postgresql серверу подключаются node.js сервера по streaming replication протоколу. Каждый сервер обслуживает определенный набор клиентов. Так как количество hot-standby серверов неограничено, и кроме того node.js сервера могут сами мультиплексировать streaming replication протокол, то система обладает негораниченной горизонтальной масштабируемостью. Каждый node.js сервер парсит протокол, извлекает изменения данных, на которые подписались клиенты, подключенные к этому серверу, и уведомляет клиентов об изменениях.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment