Как я понимаю идея которая лежит за отсеиванием ботов чуть сложней чем простая проверка fingerprint. Сервис по разному реагирует на повторные запросы с разных устройств и я предполагаю что внутри него разные fingerprint имеют разную степень доверенности
Вполне возможно что в каких-то моментах было проще в плане настройки под себя, но это получается лишняя точка отказа на нашей стороне и также необходимо тратить ресурсы на поддержку. Плюс собрать у себя хороший детектор ботов кажется довольно непростой задачей, а учитывая что боты они могут постоянно совершенствоваться придется самим постоянно допиливать этот сервис. И самое важное, пока кажется что кейс со спящим устройствам в любом случае пришлось бы решать на стороне фронта
Если я правильно понял идею - то она примерно такая же как в примере с кастомным fetch с названием customFetch_USE_IT_OR_WILL_BE_FIRED. Основная проблема что мы не можем заставить nextjs использовать наш собственный агент, а nextjs при этом также получает 403 ошибки уже при навигации между страницами
Вы кажется не учли секцию где я описывал работу с ts типами( Infer ). В цитате который вы привели говорится о:
валидации - как понимаете она сейчас есть
генерации ts типов на основании схемы - она тоже есть. В статье это Infer , в библиотеке это InferDesy
Могу предположить что вы говорите не о том что приведено в цитате, а про преобразование типов в runtime - его действительно нет, но на мой взгляд оно не является необходимым для библиотеки валидации
Benchmark, который вы привели, замеряет основную функцию библиотек - валидацию данных, zod позиционирует себя как TypeScript-first schema validation with static type inference и я использую его как валидатор в runtime, при этом если бы в zod была возможность валидировать данные без преобразования типов - я бы воспользовался ей для замеров. Если хотите могу в benchmark добавить и Valibot, но если правильно помню после беглых замеров он немного быстрее zod
В тексте нет утверждения, что я сделал тот же zod, я не собирался повторять весь его набор функционал, расшифровка названия библиотеки намекает desy - Dead Extraordinary Simple Yup . Я написал библиотеку которая построена на достаточно простых идеях валидации и в силу этого содержит минималистичный код в кодовой базе, при этом имея хорошую производительность
Если используем библиотеку для работы с формами - то вариант выше, это работает и для вложенных данных. На мой взгляд это самый приоритетный вариант и частый случай использования библиотеки валидации на клиента
Если каким-то другим образом(например из пользовательского JSON) то такой функциональности сейчас не предусмотрено(да и вряд ли кому-то понадобиться). И самое простое что приходит в голову это следующий код:
Можете привести пример когда может потребоваться асинхронная валидация? В голову приходит только работа с DB при серверном сценарии, но такую проверку обычно делают на отдельном уровне бизнес логики, а не при первоначальной валидации данных. Пока кажется что если потребовался асинхронный запрос - то это явный сигнал что проверка связана с логикой, а не форматом данных(например занято ли имя), а такие проверки я бы делал не через библиотеку
Для меня неявная трансформация данных скорее минус чем плюс. Это чуть упрощает жизнь разработчику, но добавляет неочевидность потоку данных. Если мы оперируем изначальной сущностью userData то будет странно увидеть там тип данных который пользователь не отправлял, а если на основе изначальных данных строим свои сущности - тогда это то место где можно преобразовать
Могли бы вы привести пример какой бы вы хотели видеть комбинацию данных? В моей голове пример приведенный ниже закрывает эту потребность, но возможно я что-то не учел
согласен, при клиентской валидации обязательно валидировать все данные, иначе это будет как минимум странно выглядеть. Но на мой взгляд для этого не требуется добавлять полную валидацию в библиотеку, можно обработать это на уровне библиотеки для работы с формами. Примерно так:
type Test = (value: any) => string;
class Field {
test: Test;
}
class Form {
fields: Record<string, Field>
constructor(testsObj: Record<string, >) {
for (const key in testsObj) {
this.fields[key] = new Field(testsObj[key])
}
}
}
const form = new Form(convertSchemaToTestFuncs({
name: d.string()
}))
Это избавит от необходимости в добавлении лишнего функционала и заставит думать модульно, разбивая данные на полноценные сущности
Привет. Действительное очень быстрая библиотека, что видно по твоим и моим результатамзамеров.
Но выделю несколько пунктов которых в ней не хватает лично мне:
Производительности при нахождении ошибок. $mol_data выбрасывает исключение, что сказывается на его performance. Ну и как я написал выше это не совсем правильно с моей точки зрения - валидация данных ожидаемая нами операция, а такие действия не должны выбрасывать исключения за исключением(извини за повторение) непредусмотренных проблем
Не хватает строгости проверок по умолчанию. Я бы хотел видеть максимально строгие проверки, что пока не реализовано в mol. Например в desy по умолчанию строка проверяется на то что она не пустая, а в $mol_data нет, desy в объекте могут быть только известные ключи, а в $mol_data нет
Не хвататет удобств к которым привык в yup и zod. Например проверки что значение всегда true или расширяемости кастомными проверками(возможно $mol_data_pipe можно использовать для этого, но мне показалось что он про преобразование типов)
Наверно самая большая проблема для меня - понятность кода. В моей desy эта цель стояла на первом месте. Скажу честно код $mol_data выглядит немного космически со всеми фишками из mol-а. При этом mol кажется для меня довольно сложной экосистемой, а эта библиотека связана с ней довольно сильно.
В normalizr вы обязаны заранее указывать схему. Более того normalizr инструмент другого уровня, поскольку не занимается подписками и не отслеживает изменение сущностей
Именно iresine и должна этим заниматься, синхронизируя данные в хранилище и собственном сторе.
Вероятно в описании я не слишком подробно остановился как использовать нормализацию.
В моем представлении iresine хорошо сочетается с менеджерами server-state (например react-query или swr) sandbox. Как видно из примера iresine действительно сама подменяет данные в хранилище, уведомляя об этом ui с помощью основного стейт-менеджера.
До того момента когда я начал работать 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 толератно работает с сущностями без типа, то можно добавлять нормализацию для сущностей постепенно. Никто не заставляет переписывать все и сразу. Тем более кажется это дело нескольких часов, а не недель. О бизнес выхлопе кажется можно вполне обосновано объяснить себе и менеджеру, что данные в разных частях приложения должны совпадать.
Как я понимаю идея которая лежит за отсеиванием ботов чуть сложней чем простая проверка fingerprint. Сервис по разному реагирует на повторные запросы с разных устройств и я предполагаю что внутри него разные fingerprint имеют разную степень доверенности
Вполне возможно что в каких-то моментах было проще в плане настройки под себя, но это получается лишняя точка отказа на нашей стороне и также необходимо тратить ресурсы на поддержку. Плюс собрать у себя хороший детектор ботов кажется довольно непростой задачей, а учитывая что боты они могут постоянно совершенствоваться придется самим постоянно допиливать этот сервис. И самое важное, пока кажется что кейс со спящим устройствам в любом случае пришлось бы решать на стороне фронта
Если я правильно понял идею - то она примерно такая же как в примере с кастомным fetch с названием
customFetch_USE_IT_OR_WILL_BE_FIRED
. Основная проблема что мы не можем заставить nextjs использовать наш собственный агент, а nextjs при этом также получает 403 ошибки уже при навигации между страницамиВы кажется не учли секцию где я описывал работу с ts типами( Infer ). В цитате который вы привели говорится о:
валидации - как понимаете она сейчас есть
генерации ts типов на основании схемы - она тоже есть. В статье это Infer , в библиотеке это InferDesy
Могу предположить что вы говорите не о том что приведено в цитате, а про преобразование типов в runtime - его действительно нет, но на мой взгляд оно не является необходимым для библиотеки валидации
Benchmark, который вы привели, замеряет основную функцию библиотек - валидацию данных, zod позиционирует себя как TypeScript-first schema validation with static type inference и я использую его как валидатор в runtime, при этом если бы в zod была возможность валидировать данные без преобразования типов - я бы воспользовался ей для замеров. Если хотите могу в benchmark добавить и Valibot, но если правильно помню после беглых замеров он немного быстрее zod
В тексте нет утверждения, что я сделал тот же zod, я не собирался повторять весь его набор функционал, расшифровка названия библиотеки намекает desy - Dead Extraordinary Simple Yup . Я написал библиотеку которая построена на достаточно простых идеях валидации и в силу этого содержит минималистичный код в кодовой базе, при этом имея хорошую производительность
зависит от того как мы получаем эти данные.
Если используем библиотеку для работы с формами - то вариант выше, это работает и для вложенных данных. На мой взгляд это самый приоритетный вариант и частый случай использования библиотеки валидации на клиента
Если каким-то другим образом(например из пользовательского JSON) то такой функциональности сейчас не предусмотрено(да и вряд ли кому-то понадобиться). И самое простое что приходит в голову это следующий код:
Подчеркну что в таком случае валидация будет для каждого поля отдельно, но это не очень красивый вариант и стоит по возможности его избежать
Можете привести пример когда может потребоваться асинхронная валидация? В голову приходит только работа с DB при серверном сценарии, но такую проверку обычно делают на отдельном уровне бизнес логики, а не при первоначальной валидации данных. Пока кажется что если потребовался асинхронный запрос - то это явный сигнал что проверка связана с логикой, а не форматом данных(например занято ли имя), а такие проверки я бы делал не через библиотеку
Для меня неявная трансформация данных скорее минус чем плюс. Это чуть упрощает жизнь разработчику, но добавляет неочевидность потоку данных. Если мы оперируем изначальной сущностью
userData
то будет странно увидеть там тип данных который пользователь не отправлял, а если на основе изначальных данных строим свои сущности - тогда это то место где можно преобразоватьМогли бы вы привести пример какой бы вы хотели видеть комбинацию данных? В моей голове пример приведенный ниже закрывает эту потребность, но возможно я что-то не учел
Напишите пожалуйста каким-бы вы хотели это видеть? Для себя подобного рода задачи я решаю через кастомные правила c помощью .test()
согласен, при клиентской валидации обязательно валидировать все данные, иначе это будет как минимум странно выглядеть. Но на мой взгляд для этого не требуется добавлять полную валидацию в библиотеку, можно обработать это на уровне библиотеки для работы с формами. Примерно так:
Это избавит от необходимости в добавлении лишнего функционала и заставит думать модульно, разбивая данные на полноценные сущности
Пример
convertSchemaToTestFuncs
для desy, для yupПривет. Действительное очень быстрая библиотека, что видно по твоим и моим результатам замеров.
Но выделю несколько пунктов которых в ней не хватает лично мне:
Производительности при нахождении ошибок. $mol_data выбрасывает исключение, что сказывается на его performance. Ну и как я написал выше это не совсем правильно с моей точки зрения - валидация данных ожидаемая нами операция, а такие действия не должны выбрасывать исключения за исключением(извини за повторение) непредусмотренных проблем
Не хватает строгости проверок по умолчанию. Я бы хотел видеть максимально строгие проверки, что пока не реализовано в mol. Например в desy по умолчанию строка проверяется на то что она не пустая, а в $mol_data нет, desy в объекте могут быть только известные ключи, а в $mol_data нет
Не хвататет удобств к которым привык в yup и zod. Например проверки что значение всегда true или расширяемости кастомными проверками(возможно $mol_data_pipe можно использовать для этого, но мне показалось что он про преобразование типов)
Наверно самая большая проблема для меня - понятность кода. В моей desy эта цель стояла на первом месте. Скажу честно код $mol_data выглядит немного космически со всеми фишками из mol-а. При этом mol кажется для меня довольно сложной экосистемой, а эта библиотека связана с ней довольно сильно.
В normalizr вы обязаны заранее указывать схему. Более того normalizr инструмент другого уровня, поскольку не занимается подписками и не отслеживает изменение сущностей
Именно iresine и должна этим заниматься, синхронизируя данные в хранилище и собственном сторе.
Вероятно в описании я не слишком подробно остановился как использовать нормализацию.
В моем представлении iresine хорошо сочетается с менеджерами
server-state
(например react-query или swr) sandbox. Как видно из примера iresine действительно сама подменяет данные в хранилище, уведомляя об этом ui с помощью основного стейт-менеджера.До того момента когда я начал работать c клиентом apollo, строка
this.users.set(user.id, user)
не казалась мне такой страшной. Однако вернувшись из мира graphql где нормализация есть, есть ощущение что ты пишешь лишний код. Отсутсвие строки лучше чем ее наличие, аКонтраргументы:
Если бы в приложениях не использовался никакой state-manager, то я бы согласился что это лишний слой абстракции. Однако данный слой является дополнительным к слою state-manager-a с котором уже работает разработчик и который и так уже существует. То есть для разработчика ничего не меняется в работе, ни с получением данных ни с их отрисовкой.
Поле
__typename
в моей практике было достаточно полезным. Конечно было бы идеально не добавлять полей, однако использование JSON-a как самого популярного протокола диктует свои требования. В идеальном мире мы могли бы обойтись и без добавления поляid
в данные, и сравнивать только адрес объекта в памятиunknownUser === targetUser
. Но идеального решения не существует, и добавления данных о типе это минимальная цена.Как мне кажется это стоит 0 или почти 0. Как я упоминал разработчик не сталкивается со слоем нормализации напрямую, если только не считает количество обновлений в каждом подписанном компоненте. При этом он сталкивается с нормализацией при использовании строки
this.users.set(user.id, user)
.Поскольку iresine толератно работает с сущностями без типа, то можно добавлять нормализацию для сущностей постепенно. Никто не заставляет переписывать все и сразу. Тем более кажется это дело нескольких часов, а не недель. О бизнес выхлопе кажется можно вполне обосновано объяснить себе и менеджеру, что данные в разных частях приложения должны совпадать.