Обновить
40

Пользователь

30
Подписчики
Отправить сообщение

Проще отправить эти 1000 строк на клиента - и не заставлять API зависеть от UXа клиентского приложения (которое может завтра поменяться).
Но тут уже нужно говорить о паттерне bff, о проектировании системы целиком, о качестве API - все то, что явно не попадает в контекст данной статьи (которая вообще не про качество API и не про качество реализации)

Хм, а как можно было решить эту проблему с вашей точки зрения?

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

Кстати, а какой банк предпочли?
А то я тоже был клиентом Росбанка и после него T-банк совсем не устраивает (ужасное мобильное приложение, плохие условия кэшбека и куча багов на каждом шагу).

Хм, а с чего бы маппинг не делать именно на том уровне, который служит для предоставления внутренних сущностей для внешнего потребителя, тем более что маппинг из Entity в DTO - это как раз и есть формирование ответов, это же просто один из адаптеров в Onion Architecture.
А вот протягивание формата и методов из публичного API в модель (уровень сервисов) является довольно популярной проблемой, зачем модели вообще знать, какие там entrpoints наружу торчат и какой там протокол висит. Впрочем, все это в идеальном мире, в реальности, конечно, учитывать особенности взаимодействия приходится (про это как раз идет речь в DDD Trilema)

Хм, базе на малых объемах (а тут речь идет явно о небольших базах, так как предлагаемые в статье решения не работают даже на миллионах строк) нет особой разницы - числа или строки. Хотя, конечно, писать enum в базу строкой - не всегда хорошая идея, в основном при десериализации из БД - и тут вполне можно использовать какой-то собственный парсер (тот же AttributeConverter - это не принципиально).

Но так как статья про API - меня больше смущает использование enum в API.
Да, если полностью контролировать и сам сервис и его пользователей и продакшен - то добавление нового статуса можно сделать через несколько связанных релизов. Если хотя бы одно условие не выполнено - то придется иметь две версии класса с разными Enum, что для REST-like API будет стоить довольно дорого (нужно переписать довольно много методов, фактически добавить сущность /incidents2/).
Для RPC есть, к счастью, возможность версионировать не сущность (и все-все методы работы с ней) и не весь API (как предлагают в подходах вида /api/v3/entity/), а конкретную ручку (/api/method/v1, например - там много вариантов).

И да, проблема не только в enum, но в любых несовместимых изменениях в API. Просто часто забывают, что добавление элемента в enum - как раз несовместимое изменение в протоколе.

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

Основная проблема - что для поставленной задачи использовать REST-like вообще не нужно, поэтому решение на REST уже не идеальное, а неправильное. Если уж реализовывать, то paсh обычно нужен для всей сущности, а не для отдельных полей (и да, его непросто реализовывать, но в нормальном API он нужен).
Если уж говорить о проблемах:
1) В ..Service зачем-то копируется API, хотя сервис обычно не маппится на entrypointы один к одному (например, patch обычно реализуют через update).
Зачем вообще patch-методы внутри Service - не понятно.
2) Классы Entity зачем-то сделаны mutable, еще и с конструкторами. Это не лучшая идея.
3) Если уж говорить про идеальный API, то стоит подумать про DDD, про это вообще ни слова.

В общем, статья написана явно человеком без большого практического опыта и пользы (кроме перечисления пунктов документации по Spring/Lombok) не содержит. Использовать ее как базу для реализации - не стоит.

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

Ну, тут речь шла о миллионах - там уже не будет работать быстро. Но вообще, если к разработчику пришло требование "сделай пейджинг", то первой реакцией должно быть "укажи user story, в которой нужен именно пейджинг - т.е. "пользователь решает свою проблему просматривая больше 1000 строк, кликая на следующую страницу". Если таких user story нет - то задачу просто не нужно делать, просто была ошибка в постановке. И демонстрация таких ошибок в постановке - нормальная работа даже для джуна.
А уж сделать нормальный фильтр на небольшой базе - не сложнее, чем пейджинг. При этом будет гораздо удобнее. Ну а на большой (от единиц миллионов записей) все равно нужны другие архитектурные паттерны.

Вообще, в финтехе дат гораздо больше одной, так как есть даты календартные (LocalDate), есть банковские даты (для которых неплохо бы заводить отдельный тип-алиас для LocalDate, так как их нельзя смешивать с простыми датами), есть моменты во времени (Instant).
А вот даты с часовым поясом - я не встречал еще ни разу, обычно в этом случае имеется в виду именно Instant.
Т.е. для какой-нибудь транзакции будет отдельно Instant(несколько разных), когда она была проведено, будет банковская дата обработки (не вычисляемая по Instant), будет дата отчетности (LocalDate, может отличаться от банковской даты). И все это, вообще говоря, разные типы, не предполагающие конвертации.

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

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

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

Ну, я тут про API и DTO. Как именно валидировать входящие события (в базе или в логике приложения) - отдельный вопрос. Я бы скорее валидировал на приложении, а не в базе.

Тогда нельзя говорить о "микросервисах", так как МСА - это и про независимый деплой, а тут приходится всю систему останавливать и все сервисы правильных версий накатывать и запускать.
Хотя, конечно, мало кто умеет в независимый деплой, это достаточно сложно. Потому и большинство, кто пишет "микросервис" - на самом деле имеют в виду "кусочек кода, запускаемый в отдельном процессе", даже не про сервис в смысле SOA.

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

Ну, про проектирование микросервисов и про проблемы разных видов API у меня достаточно много докладов. Из более-менее последних:
https://www.youtube.com/watch?v=Sidqt7IqMFk - про разные стили API
https://www.youtube.com/watch?v=F-6e6sfLvSc - про версионирование API и связанные проблемы
https://www.youtube.com/watch?v=hXuyT6T3fNU - про проектирование микросервисов вообще

Про дизайн API у меня докладов нет, зато есть доклады от Ромы Елизарова, от Doug Lea и от других хороших специалистов. А про ООП неплохо написано и у Буча и у Эванса.
Поэтому не совсем понятно, зачем транслировать довольно странные представления о REST в обучающих статьях (

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

Ну вот смотри, у тебя добавился еще один статус. Как и что нужно сделать в системе, чтобы обновить сервисы (желательно без останова)?

Обычно вместо enum в API - просто строчки (коды), при этом отдельная обвязка, которая как-то реализует контроль этих строчек с учетом конкретной бизнес-логики (просто сохранить что пришло; подменить неизвестное на default; выкинуть ошибку, но все равно сохранить; использовать внешний маппинг) и т.п.

Формально, изменение состава enum - это несовместимое изменение в API. Для RPC нужно заводить новый entrypoint, а в REST-like, увы, вообще нет нормальных подходов для версионирования.

Хм, а зачем начинающим разработчикам сразу давать плохие советы, еще и называть статью "идеальный API"?
Если бы статья называлась "как быстро набросать REST API на спринге не приходя в сознание" - не было бы вопросов. Но в статье нигде не говорится о том, что изначальная постановка - плохая, что если вас просят написать REST API как в статье - то нужно убегать из компании с таким низким уровнем качества и таким плохим проектированием.
И, кстати, вот подобные советы были бы джуниорам гораздо полезнее, так как быстрее сделали бы их миддлами.

Использование enum для статусов - вообще очень стремная идея, так как очень сложно потом будет расширять список (а список статусов часто меняется).

Информация

В рейтинге
4 657-й
Работает в
Зарегистрирован
Активность