Как стать автором
Обновить

Комментарии 7

По мне так строчка this.users.set(user.id, user) выигрывает по сравнению с созданием слоя нормализации с эвент-эмиттером, изменением большого количества сущностей с добавлением лишнего type, большого оверхеда по обучению команды и поддержанию единообразия. И в итоге идеально все равно не получится — будут легаси-ручки бэка или сторонних интеграций, данные в которых не поменять, и "нормализация" кашеобразно распараллелится на фронт и бэк. Да и в самом фронте соблюдать получится только при создании нового проекта, так как внедрять подобный слой в существующую кодовую базу дело недель работы без какого-либо бизнес-выхлопа, кроме негативного — увеличения сложности поддержки.


Статью внимательно прочитал, но так и не понял, зачем это нужно. Хранилища в памяти с ключом по id в моей практике пригождались только 2 раза — при получении частичных данных (например, user) в десятке разных ручек (но выбранный подход с нормализацией оказался в итоге не самым эффективным, добавив значительный оверхед) и при необходимости скорости доступа О1 в требовательных к перфомансу интерфейсах при наличии 10к+ элементов в массиве. В остальных случаях store.update(store.users, user), где update соответствующей стратегией находит целевой элемент или создает новый, идеальный вариант.

До того момента когда я начал работать c клиентом apollo, строка this.users.set(user.id, user) не казалась мне такой страшной. Однако вернувшись из мира graphql где нормализация есть, есть ощущение что ты пишешь лишний код. Отсутсвие строки лучше чем ее наличие, а


То, что может быть автоматизировано, должно быть автоматизировано

Контраргументы:
созданием слоя нормализации

Если бы в приложениях не использовался никакой state-manager, то я бы согласился что это лишний слой абстракции. Однако данный слой является дополнительным к слою state-manager-a с котором уже работает разработчик и который и так уже существует. То есть для разработчика ничего не меняется в работе, ни с получением данных ни с их отрисовкой.


изменением большого количества сущностей с добавлением лишнего type

Поле __typename в моей практике было достаточно полезным. Конечно было бы идеально не добавлять полей, однако использование JSON-a как самого популярного протокола диктует свои требования. В идеальном мире мы могли бы обойтись и без добавления поля id в данные, и сравнивать только адрес объекта в памяти unknownUser === targetUser. Но идеального решения не существует, и добавления данных о типе это минимальная цена.


большого оверхеда по обучению команды и поддержанию единообразия

Как мне кажется это стоит 0 или почти 0. Как я упоминал разработчик не сталкивается со слоем нормализации напрямую, если только не считает количество обновлений в каждом подписанном компоненте. При этом он сталкивается с нормализацией при использовании строки this.users.set(user.id, user).


дело недель работы без какого-либо бизнес-выхлопа

Поскольку iresine толератно работает с сущностями без типа, то можно добавлять нормализацию для сущностей постепенно. Никто не заставляет переписывать все и сразу. Тем более кажется это дело нескольких часов, а не недель. О бизнес выхлопе кажется можно вполне обосновано объяснить себе и менеджеру, что данные в разных частях приложения должны совпадать.

"Отсутствие строки лучше чем ее наличие" — так же относится и к двум дополнительным параметрам, дополнительному слою, дополнительной библиотеке и документации. Этих строк с partialAssign будет ну пара десятков на среднее приложение, а размер библиотеки, включенной в бандл и код обвязки займет явно намного больший объем, увеличив и количество поддерживаемых компонентов системы. Поэтому аргумент звучит неубедительно.


Я очень сомневаюсь, что это стоит 0, вообще-то это все довольно дорого.


Как я понял, в целом эта система нужна, если одинаковые запросы шлются из разных компонентов и данные складываются в разные хранилища, и именно для этого нужны "глобальные id для всех сущностей". В реальности за несколько лет мне не попадалось таких "архитектур" — если данные используются в нескольких компонентах, то они выносятся в глобальное хранилище (redux, mobx) и их обновление происходит явно, id нужен только для partialUpdate. Поэтому я так и негативно отнесся к предложениям в статье. Но если действительно приложение так построено, что данные и методы их получения многократно дублируются и раскиданы по локальным сторам, то подобная нормализация, безусловно, нужна. Как нужно и переписывание архитектуры ядра, на мой взгляд.


"для разработчика ничего не меняется в работе, ни с получением данных" — вот это все равно звучит очень странно. Нормализованные или ненормализованные данные все равно же надо положить в хранилище, не будет же iresine этим заниматься? Или подразумевается, что все полученные данные вместо redux или mobx будут храниться в некоем iresineStore и напрямую получаться оттуда вместо других хранилищ без системы синхронизации с основным стором?

Именно iresine и должна этим заниматься, синхронизируя данные в хранилище и собственном сторе.


Вероятно в описании я не слишком подробно остановился как использовать нормализацию.
В моем представлении iresine хорошо сочетается с менеджерами server-state (например react-query или swr) sandbox. Как видно из примера iresine действительно сама подменяет данные в хранилище, уведомляя об этом ui с помощью основного стейт-менеджера.

То есть берется инструмент запросов с неявным внутренним хранилищем, неявно там что-то нормализуется и преобразовывается с помощью мидлвары… Для остальных интеракций, видимо, будет заведен другой стейт-менеджер, и каким-то образом нужно будет синхронизировать с этим react-query… Что-то вообще не понимаю смысла всего этого.


Я мыслю в категориях api.getUser(user => store.createOrUpdate(store.user, user)) и render() { return <>{this.context.store.users}</> } с разделением слоев апи, модификаторов стора, хранилищ и реакт-компонентов, отвечающих за View. Запросы из компонентов и параллельные сторы, неявные трансформации и технические параметры в данных — это для меня другой мир...


Ну, может, кому-то пригодится.

В normalizr вы обязаны заранее указывать схему. Более того normalizr инструмент другого уровня, поскольку не занимается подписками и не отслеживает изменение сущностей

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории