Hi there! I'm Aleks 🧑💻. It's nice to virtually meet you!
I started a few RU-vid series like Weekly Links and [Leet] Code with me to show that software engineering still can be fun! By sharing news and experience this way I hope I help you to grow as developers as well.
Хороший доклад, спасибо. Однако, могучий народный перст указал на правильный путь: k8s, helm, и да прибудет с вами микросервисное щастье. У кого побольше денег - openshift. И инфраструктура будет настолько далеко от бизнесового кода, что они вообще ниразу друг друга не встретят.
В ликви же не только xml, а ещё и sql и yml формат поддерживается) Если принимаете идеи, то интересно посмотреть на разбор именно продвинутых функций ликвибейза, например передача переменных из пропертей в файлы миграций, команда не падать если имеющаяся миграция изменена и прочее (я знаю только эти из реальных проектов, а хотелось бы понимать все возможности)
Еще в ликвибейз можно закинуть все связаные скрипты в один sql-файл и разбить на разные чейнджсеты. Еще и чейнджсетам можно дать нормальные имена, а не непонятные id. Ну и при сборке, ликвибейз можно отделить от имеджа основного приложения, но это уже больше CI/CD.
А разве Document и так не содержит поле DocumentType? Разве не правильнее в него и из него конвертировать? А то выйдет что формат документа поменяется, а тест всё еще проходит.
Привет! Да, в документе есть поле типа DocumentType и класс Document для теста тоже подходит. Однако, представим, что в класс Document содержит больше полей, тогда все их придется в тесте инициализировать и обрабатывать. С другой стороны, если DocumentType нигде кроме класса Document не используется, можно и для теста его использовать. Так что, как обычно, все зависит от скойпа. Здесь в тесте я хотел показать именно сереализацию-десериализацию одного поля в изоляции, поэтому и добавил отдельный класс.
Александр, а можете посоветовать материалы по интеграционному тестированию? Чтобы с 0 погрузиться Мы работаем с интеграционными тестами бд, но я делаю это вслепую почти)
Классное видео! Разберите пожалуйста полную и правильную настройку objectMapper в spring boot приложении, до конца не понятен смысл всяких там findAndRegisterModules, подключение всяких разных serialization features
Я в следующей серии хотел сделать то же самое но с использованием Jackson-а - там есть несколько вариантов - на аннотациях и через собственный десериализатор.
Для повторных запросов хорошо подходит optimistic lock, например по timestamp. Обновил запись - обновил timestamp. Если не одной записи не обновилось - вернуть 422. Второй запрос по дефолту будет 422 возвращать, так как не сможет обновить запись. Что касается создания чего-то - тут unique index поможет. Ну или можно вынести это в логику приложения, но будет сложнее читать и придется делать транзакцию, чтобы никто не обновил запись, пока мы проверяем. Где лучше эту логику держать: бд или сервис - хороший вопрос. Но клиенту доверять точно не стоит, даже если он какой-то ключ будет кидать. Кто его знает, может он на повторный запрос кинет новый ключ. Как по мне, выглядит как накручивание лишней логики.
> Если не одной записи не обновилось - вернуть 422. Второй запрос по дефолту будет 422 возвращать, так как не сможет обновить запись. В таком случае логика должна быть сразу реализована с поддержкой идемпотентности. > Что касается создания чего-то - тут unique index поможет. Предположим, вы переводите некоторую сумму с аккаунта А на аккаунт Б. В данном сценарии индекса будет недостаточно. > Кто его знает, может он на повторный запрос кинет новый ключ. Идея как раз в том, чтобы на все повторы одного и того же запроса был один и тот же ключ. Как обычно - есть сценарии, в которых можно обойтись без внешнего ключа, есть те, в которых не получится.
@@ABarmin 1. Может я что-то недопонимаю, но мы тут не вернем тот же результат. В первом запросе мы обновим данные и вернем новые,, на второй запрос вернем 422. 2. Вопрос был про создание, на создание индекса должно хватить, не вовсех случаях, но все же. Что касается перевода денег, то данная операция должна быть атомарной, не зависимо от ключа. 3. Не думаю, что бекенд должен доверять фронтенду. В целом, мой поинт в том, что логика с ключем - усложнение приложения. Нам в любом случае нужно добавлять логику, если придет одинаковый запрос с разными ключами (два клиента сделали одно и тоже в одно время). Добавлять к этому еще логику, где мы храним результат прошлого запроса по ключу, довольно перегружает логику. Проще сказать фронту, чтобы тот рефрешнул данные.
Стоит отметить, что общий случай довольно сложно себе представить. Представьте, что запрос в стороннюю систему был отправлен, обработан, но ответ клиентом не получен - случилась проблема с сетью. В этом случае клиент может отправить запрос еще раз. Если для сервера запрос идемпотентный, он может вернуть тот же ответ еще раз, например, извлечь данные из БД и просто вернуть. Если же запрос для сервера не идемпотентный, например, создание записей в БД, то повторная обработка запроса приведет к созданию дублирующих записей. В этом случае у сервера опять же есть несколько вариантов действия - вернуть 422 или вернуть уже созданную запись. А теперь наиболее сложная часть - как убедиться, что повторный запрос действительно повторный, а не второй такой же? Вариантов несколько: Во-первых, можно попробовать использовать уникальный индекс в базе данных. Вариант подходит если запрос можно уникально идентифицировать по совокупности полей, но не подходит, когда может прийти второй такой же запрос. Второй способ - каждому взаимодействию можно присвоить уникальный идентификатор (напомню, что клиент не всегда браузер, это может быть и второе серверное приложение). Такие образом повторный (не второй такой же, а именно повторный) запрос будет иметь тот же самый идентификатор и будет обработан только один раз. На самом деле, это не очень частный сценарий при взаимодействии фронтенда и бакенда, но довольно частый сценарий при взаимодействии между сервисами в бакенде. В общем виде - ключ позволяет отделять повторные запросы от последовательных запросов с одинаковыми данными.
Александр, если у вас есть время для этого, то сделайте какой-нибудь исчерпывающий курс по какой-то важной для понимая темы. Я взглянул, у вас есть плейлист с курсом от Epam, но он 2017 года и он очень длинный, его смотреть будет сложновато. В целом, если у вас есть такой опыт преподавания, то было классно увидеть Ваш новый и актуальный курс, например, по Spring. Было бы до невозможности круто увидеть от вас курс по Spring AI хотя бы до базового уровня))
@@ABarmin Будет интересно абсолютно все, где есть необходимая база по теории и практическое применение, так что при желании и наличии времени выпускайте все что есть))) Вообще было бы классно понять как изучать какую-то технологию не по курсам, а по документации. Курсы - это классно, но думаю многим хочется стать независимыми, но я когда пытаюсь хоть что-то делать по документации, то это превращается в кучу боли. Возможно есть какие-то принципы и подходы для того, чтоб изучить документацию, но которые многие не знают. Вот если бы кто-то с большим опытом объяснил как работать с докой, как оптимально учиться и тд, было бы бомбезно. Банальный пример - Spring AI, новая технология, курсов по ней ещё нет, и что делать? как самому во всем разобраться? Читать документацию на английском от корки до корки? или быстро просматривать какие-то куски? Если, вдруг, Вам нужна будет идея ролика или цикла роликов - возьмите на заметку, потому что уметь работать с документацией - важнее чего-либо.
Удобно хранить дату в UTC, а в коде использовать лонг, который и на ui возвращать, который, в свою очередь, лучше знает где пользователь находится и сам прокручивает время.
Я так полагаю, имеется в виду жаваскриптовый Date, который по умолчанию отображает время в часовом поясе пользователя - тоже вариант. Стоит иметь в виду, что не очень хорошо подходит для разных админок, где нужно показать админу (который в другом часовом поясе) во сколько произошло событие (в часовом поясе пользователя). Чем дольше я занимаюсь разработкой, тем больше понимаю, сколько разных нюансов нужно каждый раз держать в голове чтобы решить даже такую простую задачу как отображение даты.
@@ABarmin Это уже похоже на какой-то аудит. Тут, мне кажется, нет смысла усложнять всю систему преобразованием даты и стоит сохранять часовой пояс пользователя только в аудите, а дату также хранить в UTC. Действительно, везде есть свои нюансы, но кмк, всегда стоит смотреть на самый простой вариант, ибо чем больше будет накрученно такой логики, там сложнее будет поддерживать и развивать приложение. И тут появляется вопрос: а стоило ли оно того?
Как обычно, уровень сложности зависит от требований. Можно начать с самого простого варианта и хранить дату-время как получится и затем по мере изменения требований постепенно усложнять и поддерживать новые возможности. Здесь как везде - важно не переусложнять с самого начала, но при этом оставлять какую-то возможность для расширения и обновления.
@@ABarmin Можно просто ознакомительное видео - что это, как и зачем можно использовать, в чем отличие от хибера. Можно еще пример использования со spring boot.
Шаблон проекта, по которому создаются новые сервисы. Ближайший аналог - Maven Archetype, из которого можно сразу создать проект с нужной структурой пакетов, заранее добавленными зависимостями и, например, сконфигурированными метриками.
Александр, здравствуйте, я студент, изучаю Java. Написал простенькое CRUD приложение на Spring и подключил PostgreSQL, но хочу как можно скорее найти первую работу и с чистой совестью сказать, что я знаю Spring и могу что-то на нем написать. Что бы вы могли посоветовать, чтобы оптимизировать затраты времени и получить максимальный результат?
Отличный вопрос и на него нет простого совета. Если цель - сказать, что знаете Спринг, то однозначно рекомендую посмотреть видео Евгения Борисова, прямо все, какие сможете найти. Вторая рекомендация - повторить все, что рассказывает Евгений в своих видео - сделать небольшой пет-проект, сделать попробовать использовать стартеры, использовать внедрение зависимостей, разобраться, как работает MVC и Spring Data, попробовать написать свой стартер. Все эти рекомендации можно обобщить - попробуйте Спринг в деле, не только в теории. Мне кажется, так получится оптимизировать время обучения. Ах да, есть еще один трюк - попробуйте написать свой небольшой IoC/DI контейнер, маленький спринг такой. Коммерческой ценности в этом нет, зато однозначно поможет разобраться как многие вещи работают под капотом.