Выпуск 33: Базы данных вверх тормашками

В сером осеннем Берлине мы встретились с создателем Swarm Виктором Грищенко (@gritzko) и взяли у него интервью. Говорим о синхронизации данных в многопользовательских приложениях, различных NoSQL хранилищах и планах развития проекта.

В новостном блоке обсуждаем GraphQL, Angular Universal и Redux.

Скачать выпуск (mp3, 44 MB)
  • brackets-arrows

    Relay lets you mutate data on the client and server using GraphQL mutations, and offers automatic data consistency, optimistic updates, and error handling.
    а по описанию прям метеор)может вы про релей подробнее расскажите(или напишите)?

    • У меня нет столько опыта, чтобы про него подробнее рассказать. Может знаете, кого позвать в подкаст, чтобы обсудить эту тему?

      • brackets-arrows

        сказанное в подкасте меня чет задело и я прошел learngraphql =D
        по тому что я увидел мутации в graphql это по большому счету такой стандартизированный RPC(+ из коробки валидация, автоматические оптимистичные апдейты(да прям как в метеоре – накатили на клиенте до потверждения бекенда а когда бекенд ответил внесли правки если надо) и обработка ошибок) – нельзя сказать что в “там ничего нет про изменения данных”. Причем это сделано глобально, а не так что для каждого метода надо каждый раз писать обвязки.
        Судя по тому какие я видел бекенды для SPA – все так или иначе пытаются придумать чтото подобное, только у всех свои велосипеды и получается как правило хуже(по понятным причинам).Graphql это просто попытка стандартизировать бардак в мире серверной части фронтенда – никаких новых концепций в нем нет. Этакая хорошая реинкарнация WSDL(@Константин Буркалев:disqus должно понравится).
        насчет того что там нет ничего про решение конфликтов итд – я думаю что логично было бы придумать swarm-graphql 🙂 Вообще внешний бекбон-лайк интерфейс swarm мягко говоря ниочень – использование его с тем же реактом под большим вопросом
        имхо было бы неплохо если бы swarm превращался больше в такое миддлваре не завязанное на клиент или сервер – сейчас вопросы интеграции swarm с существующим клиентом и сервером крайне болезненны и зачастую мешают его внедрению

        • Да, полностью согласен, что это попытка стандартизовать клиент-серверное взаимодействие, но уже с использованием современных подходов.

  • Deonis Peretyagin

    По поводу redux – можно же из этого большого объекта с данными выкусывать только нужную для конкретного компонента информацию

    • filipovskii_off

      Можно, но тогда возникает 2 проблемы.

      1. Получится два независимых приложения (старый на flux и новый на redux) которые нужно будет дружить. Передавать actions из одного dispatch в другой.

      2. Выкусывать данные для компонента значит также выкусывать зависимости этих данных. Так по цепочке придётся много stores переколбасить.

      По этим двум причинам решили пойти другим путём.

  • vitvad

    > избавиться от Ruby для Sass
    а libsass и https://github.com/sass/node-sass не решает проблему ? насколько я помню разработчики обещали синхронизировать выпуск фич для sass с этой либой больше года назад.

    > object Observe
    мизерный процент использования, мне кажется, из-за отсуствия поддержки и адекватной возможности сделать полифил. Для меня это самая ожидаемая фича языка. Абсолютно не понимаю разговоров про feature deprecate.

    • filipovskii_off

      > object Observe

      Поделитесь как вы его планируете использовать? Отсутствие подписки на глубокие изменения в объектах/массивах не смущает?

  • Oleg Orlov

    Подскажите как подключить Definitely Typed к проекту не на TypeScript. Использую Atom IDE, хочу получить autocomplete.

    • Я прикручил в IntelliJ-продуктах с помощью tsd. tsd может установить нужные файлы в папочку вашего проекта в независимости от IDE или редактора, но будет ли ваш Atom анализировать эти файлы и дополнять автокомплит, это я не уверен.

      • chico

        будет

  • ничего не мешает делать несколько сторов в redux. просто вы не сможете использовать react-redux (точнее не всегда сможете)

  • с redux не обязательно прокидывать все через рутовый компонент

    • filipovskii_off

      А какие варианты?

      • без react-redux: создаем компоненты-контейнеры, в нужных местах и вручную подписываем их на стор в componentDidMount, где берем нужные данные и прокидываем их ниже вместе пропсами родителя.
        с react-redux: компоненты-контейнеры создаются с помощью connect и нужные данные выбираются в селекторе.

  • кстати, это я тот самый добрый россиянин, который нашел тот самый баг в демке swarm.js
    😀
    https://github.com/gritzko/swarm/issues/36

  • Хочется прокомментировать и обсудить пару замечаний про Redux.
    В частности, были озвучены некоторые проблемы, которые, на самом деле являются мифами:
    “Всё состояние хранится в одном большом объекте и этот объект передаётся в top-level (root) компонент, и потом приходится пробрасывать данные по иерархии вниз, что не очень удобно для большого приложения”

    “Всё состояние хранится в одном большом объекте” – это не миф, это действительно так, а вот что не совсем так: “и этот объект передаётся в top-level (root) компонент, и потом приходится пробрасывать данные по иерархии вниз”.

    Да, действительно, авторы Redux рекомендуют этот единый объект состояния передать в top-level (root) компонент и для больших приложений это может выглядеть не очень удобно. Но нет никаких технических ограничений делать именно так! Redux + react-redux позволяют пробросить любую _часть_ дерева состояния в _любой_ React компонент в дереве компонентов, и совсем не обязательно делать это в top-level компоненте.

    Процитирую доки http://redux.js.org/docs/basics/UsageWithReact.html
    Then, we wrap the components we want to connect to Redux with the connect() function from react-redux. Try to only do this for a top-level component, or route handlers. While technically you can connect() any component in your app to Redux store, avoid doing this too deeply, because it will make the data flow harder to trace.

    Обратите внимание на фразу “technically you can connect() any component in your app to Redux store” – технически данные можно передать напрямую в любой компонент.

    Встречный вопрос, который может возникнуть после прочтения этой фразы: “хорошо, что я могу любому компоненту напрямую передать Redux store, но моим компоненам в глубине дерева не нужен весь Redux store, я хочу лишь частичку данных о состоянии, как быть?”

    Ответ опять же в доках http://redux.js.org/docs/basics/UsageWithReact.html
    Any component wrapped with connect() call will receive a dispatch function as a prop, and any state it needs from the global state.

    Обратите ванимание на фразу “…will receive any state it needs from the global state” – т.е. в каждый конкретный react компонент вы можете передать любую сколь угодно маленькую часть общего дерева состояния, и это регулируется первым параметром функции connect().

    • filipovskii_off

      Я согласен, что это возможно в теории, ограничения redux тут нет. Но на практике это как раз то от чего мы хотим уйти. Подход который ты предлагаешь подразумевает что store доступен из любого компонента. То есть делать его синглтоном, опять.

      Понятно, что это возможно, но
      * тестировать компоненты, которые зависят на сторы сложнее чем те, которые принимают только данные и колбеки

      * делать стор синглтоном может привести к неприятным последствиям.

      • это не совсем верно. он не будет синглтоном. он создается динамически. и более того их может быть создано много. доступность сторов компонентам — это деталь реализации. в react-redux стор передается через контекст. передавая вообще все сторы через пропсы можно столкнуться с еще большими неприятностями. я бы не советовал.

        • filipovskii_off

          Контекст, да, тоже вариант. Стор будет создаваться динамически.. один раз) Чем не синглтон? Про несколько сторов вообще непонятно, зачем? И как их дружить если экшены могут менять состояния в обоих? Понятно, что можно что-нибудь придумать, но получится франкенштейн.

          Как люди делают это в Om/Elm интересно?

          • один раз на каждый инстанс приложения. проблемы синглтонов в проблемах с универсальными приложениями. на сервере будет создаваться новый инстанс сторов заново.
            про несколько сторов – это очень долгая и нудная история, не хочется тратить силы для публикации ее в комментариях тут. оставлю просто ключевые слова: sideways loading, реактивность.
            Om и Elm – совершенно другие и отличные друг от друга концепции. а также еще есть новый Om, в котором еще одна. В Om используются линзы, в Elm – сигналы и диспатчеры, гарантирующие последовательность сигналов

          • экшны не должны менять состояния в обоих. это скорее всего проблема нормализации. если же действительно должны, то нужно диспатчнуть этот экшн в оба стора

          • brackets-arrows

            Om вроде как переползает на datascript насколько помню
            Идея ваше такая как я понял – стейт един но мы можем резать его на нужные нам кусочки через прослушивание изменений кусочка стейта(в датаскрипт тоже подобное скоро должно быть – точнее уже есть но не вмерджено еще – пригласите Никиту и помучайте его на эту тему)

      • Maxim Sukharev

        на мой взгляд проблем с тестирование особо нет. Файл должен экспортировать компонент, который принимает пропсы и контейнер, который умеет эти пропсы получать из стора. При этом контейнер это просто connect(mapStateToProps)(Component). Для тестирования компонента стор не нужен. mapStateToProps так же можно эспортировать и тестировать независимо. Тестировать connect смысла нет :).

        Ден Абрамов очень-очень дохотчиво это все объясняет начиная вот с этого видео и до конца:
        https://egghead.io/lessons/javascript-redux-extracting-container-components-filterlink

        То что стор очень похож на синглтон (мы создаем инстанс в рут компоненте и дальше прокидываем его по всему приложению) верно, но все же это не синглтон, т.к. для каждого теста mapStateToProps создается новый инстанс стора. Про какие последствия ты говоришь?

  • sashashakun

    К сожалению удручающее качество звука в интервью не позволило дослушать выпуск до конца. Такая же ситуация была и с выпуском с записанными в Екб интервью(

    • К сожалению, все дело в полевых условиях. Мы пока не очень научились делать качественную запись вне домашних студий. Но будем стараться!

  • lega911

    У Object.observe нет проблем с глубокой подпиской, её нет из коробки (по понятным причинам), но оно не сложно реализуется через рекурсивное подписывание (так же как и с Object.defineProperty и Proxy), сейчас O.O используется в Polymer, Aurelia и Angular Light 0.8 – http://habrahabr.ru/post/250589/

    O.O может работать в синхронном режиме, а не только в асинхронном как многие думают, хотя не хватает режима аналогичного в defineProperty (не медленный вызов).

    Но главная проблема – это сложность интегрирования, создания механизма одинаково работающего на старых и новых браузерах с O.O, поэтому его не спешат везде внедрять, из-за этого его и выпиливают.

    Так же O.O относительно медленный, хотя это скорее всего связанно с тестовой реализацией.

    Ещё есть Proxy из ES6, он будет использоваться как “замена” O.O, но там тоже все как хотельось бы.

  • missingdays

    Вырезание лишних экспортов называется tree shaking (название пришло, видимо, из rollup.js). И оно работает только при import { anything } from anywhere. Если импортнуть весь модуль – текущий алгоритм не будет смотреть, какие функции вы используете из него, а какие нет.
    А мультик вроде “Баба Яга против” называется, если ничего не путаю.

  • Скоро ли будет новый подкаст? 🙂