Всем привет!
Уже прошел примерно год как появился ChatGPT. Его активно пытаются применить везде - для решения бизнес-задач, автоматизации рутины и конечно же написания кода. Какую же рутину можно автоматизировать в разработке? А например такую - https://github.com/Nutlope/aicommits
#git #commit
Уже прошел примерно год как появился ChatGPT. Его активно пытаются применить везде - для решения бизнес-задач, автоматизации рутины и конечно же написания кода. Какую же рутину можно автоматизировать в разработке? А например такую - https://github.com/Nutlope/aicommits
#git #commit
GitHub
GitHub - Nutlope/aicommits: A CLI that writes your git commit messages for you with AI
A CLI that writes your git commit messages for you with AI - Nutlope/aicommits
image_2024-02-05_18-02-46.png
173.1 KB
Всем привет!
Не так давно появилась такая технология как Function as a Service или сокращено FaaS. Ее цель - затащить в облако все кроме написания кода. Сегодня нашел неплохую картинку, иллюстрирующую ее на примере сервисов Google.
Слева - это как раз FaaS. Т.е. мы отдаем на откуп облачного провайдера железо и виртуальные машины (instance), управление контейнерами, runtime (JDK,.NET framework), веб сервер и даже веб контроллер (single-endpointed). И хоть тут это не указано - CI\CD pipeline.
Плюсы:
1) сопровождение и DevOps уходят на аутсорс.
Минусы:
1) vendor lock, хотя стандарт разрабатывается,
2) платим за время работы кода и платим достаточно дорого,
3) не подходит для выполняющихся долго или висящих в памяти постоянно процессов
#cloud #faas
Не так давно появилась такая технология как Function as a Service или сокращено FaaS. Ее цель - затащить в облако все кроме написания кода. Сегодня нашел неплохую картинку, иллюстрирующую ее на примере сервисов Google.
Слева - это как раз FaaS. Т.е. мы отдаем на откуп облачного провайдера железо и виртуальные машины (instance), управление контейнерами, runtime (JDK,.NET framework), веб сервер и даже веб контроллер (single-endpointed). И хоть тут это не указано - CI\CD pipeline.
Плюсы:
1) сопровождение и DevOps уходят на аутсорс.
Минусы:
1) vendor lock, хотя стандарт разрабатывается,
2) платим за время работы кода и платим достаточно дорого,
3) не подходит для выполняющихся долго или висящих в памяти постоянно процессов
#cloud #faas
Всем привет!
В продолжение темы облачных сервисов - https://telegra.ph/Urovni-pogruzheniya-v-oblako-02-06
#cloud #k8s #openshift #spring
В продолжение темы облачных сервисов - https://telegra.ph/Urovni-pogruzheniya-v-oblako-02-06
#cloud #k8s #openshift #spring
Telegraph
Уровни погружения в облако
В предыдущем посте я говорил про FaaS - Function as a Service. Это максимальная степень передачи инфраструктуры разработки в облако - все кроме кода. Больше - это только пользоваться готовым сервисом - Software as a Service. Захотелось посмотреть - а что…
Всем привет!
Периодически я вижу в коде такую ситуацию.
Есть метод с 5 параметрами, надо передать ему еще 5. Если сделать это "в лоб" - и выглядит ужасно, и SonarQube ругается.
Что можно сделать?
Ну, например, завести объект XYZParams. По сути DTO, используемую в двух классах - вызывающем и вызываемом.
Мне это решение изначально не понравилось, но я не сразу смог объяснить чем именно) Самое простое объяснение - выглядит как lifehack. Требует SonarQube меньше параметров - вот тебе один параметр. Но объяснение мне не нравилось, стал копать дальше.
И как часто бывает - набрел на статью метра, почему это плохо.
https://martinfowler.com/bliki/LocalDTO.html
Советую почитать и вообще занести этот сайт себе в закладки.
Но если вкратце:
1) DTO - как Transfer объект был создан для передачи по сети, когда велики накладные расходы. Ну или для удовлетворения требований безопасности
2) новая DTO - это всегда маппинг, как минимум односторонний. Маппинг - потенциальный источник ошибок при изменениях
3) и добавка от меня: если доменную модель со всех сторон обложить DTO и маппингами - а зачем она тогда вообще нужна?)
Решение же проблемы может быть два:
1) завести подходящие доменные объекты и передавать их, а не одиночные параметры
2) реорганизовать логику, чтобы одному методу не требовалось столько данных
#arch #dto
Периодически я вижу в коде такую ситуацию.
Есть метод с 5 параметрами, надо передать ему еще 5. Если сделать это "в лоб" - и выглядит ужасно, и SonarQube ругается.
Что можно сделать?
Ну, например, завести объект XYZParams. По сути DTO, используемую в двух классах - вызывающем и вызываемом.
Мне это решение изначально не понравилось, но я не сразу смог объяснить чем именно) Самое простое объяснение - выглядит как lifehack. Требует SonarQube меньше параметров - вот тебе один параметр. Но объяснение мне не нравилось, стал копать дальше.
И как часто бывает - набрел на статью метра, почему это плохо.
https://martinfowler.com/bliki/LocalDTO.html
Советую почитать и вообще занести этот сайт себе в закладки.
Но если вкратце:
1) DTO - как Transfer объект был создан для передачи по сети, когда велики накладные расходы. Ну или для удовлетворения требований безопасности
2) новая DTO - это всегда маппинг, как минимум односторонний. Маппинг - потенциальный источник ошибок при изменениях
3) и добавка от меня: если доменную модель со всех сторон обложить DTO и маппингами - а зачем она тогда вообще нужна?)
Решение же проблемы может быть два:
1) завести подходящие доменные объекты и передавать их, а не одиночные параметры
2) реорганизовать логику, чтобы одному методу не требовалось столько данных
#arch #dto
martinfowler.com
bliki: Local D T O
a bliki entry for Local D T O
Всем привет!
Вытяну ссылку из комментариев сюда: https://youtu.be/hUzpe73Oa3g?si=c_dY1YU2Cc_F8YiY
Хороший ролик про границы применимости паттерна Value Object.
На всякий случай - что такое Value Object и чем он отличается от DTO - https://matthiasnoback.nl/2022/09/is-it-a-dto-or-a-value-object/
Также стоит отметить, что данный паттерн является одним из основных в DDD - Domain Driven Development.
А по видео у меня такой краткий вывод - а точнее два:
1) у любого паттерна есть своя область применения
2) когда вы придумали некий хитрый лайфхак, перед тем как реализовывать его в коде стоит взять паузу и подумать.
Насколько он понятен для новичка? Не усложнит ли он код? Насколько? Не станет ли поддержка такого кода сложнее? Не добавит ли он в вашу модель "уязвимость", позволяющую использовать классы и методы не так, как задумывалось изначально?
Часто лучше написать больше простого кода, чем меньше, но неочевидного и допускающего неверное использование. И далее либо разбить этот код на микросервисы, либо на модули - например, см. мой пост про Modulith - https://t.me/javaKotlinDevOps/143
#patterns #arch #dev_compromises
Вытяну ссылку из комментариев сюда: https://youtu.be/hUzpe73Oa3g?si=c_dY1YU2Cc_F8YiY
Хороший ролик про границы применимости паттерна Value Object.
На всякий случай - что такое Value Object и чем он отличается от DTO - https://matthiasnoback.nl/2022/09/is-it-a-dto-or-a-value-object/
Также стоит отметить, что данный паттерн является одним из основных в DDD - Domain Driven Development.
А по видео у меня такой краткий вывод - а точнее два:
1) у любого паттерна есть своя область применения
2) когда вы придумали некий хитрый лайфхак, перед тем как реализовывать его в коде стоит взять паузу и подумать.
Насколько он понятен для новичка? Не усложнит ли он код? Насколько? Не станет ли поддержка такого кода сложнее? Не добавит ли он в вашу модель "уязвимость", позволяющую использовать классы и методы не так, как задумывалось изначально?
Часто лучше написать больше простого кода, чем меньше, но неочевидного и допускающего неверное использование. И далее либо разбить этот код на микросервисы, либо на модули - например, см. мой пост про Modulith - https://t.me/javaKotlinDevOps/143
#patterns #arch #dev_compromises
YouTube
Семен Киреков — Spring, Hibernate, паттерн Value Object и границы его применения
Ближайшая конференция — JPoint 2025, 3–4 апреля (Москва + трансляция).
Подробности и билеты: https://jrg.su/T2zfbS
— —
При разработке ПО всегда заходит вопрос о валидации и корректной работе с данными. Если выполнить бизнес-операцию с неверными входными…
Подробности и билеты: https://jrg.su/T2zfbS
— —
При разработке ПО всегда заходит вопрос о валидации и корректной работе с данными. Если выполнить бизнес-операцию с неверными входными…
Всем привет!
Есть такой интересный вопрос - можно ли поместить СУБД в облако?
Если отвечать на него строго технически - да, можно, для этого в k8s есть специальные типы объектов - StatefulSet https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/ и PersistentVolume
https://kubernetes.io/docs/concepts/storage/persistent-volumes/
которые обеспечивают ряд требуемых для СУБД характеристик:
1) подключенное хранилище не удаляется при каждой остановке пода
2) экземпляр StatefulSet имеет постоянное имя
3) процедура масштабирования StatefulSet в обе стороны последовательна - поды добавляются\удаляются по одному
Более того, в документации кубера есть пример с раскатыванием MySQL https://kubernetes.io/docs/tasks/run-application/run-replicated-stateful-application
Причем с возможностью автоматического масштабирования на чтение. Пример на самом деле меня впечатлил: сотня строк манифестов yaml - и БД уезжает в облако.
Так ли все хорошо?
Конечно же нет)
Для начала я бы задал типичный "менеджерский" вопрос - какую задачу решаем?
Первый момент - горизонтальное масштабирование на чтение можно обеспечить для любой СУБД. Как в облаке, так и без облака. На запись - только для NoSQL хранилищ с поддержкой шардирования.
Второй момент: сопровождение СУБД - это не просто гарантия наличия работоспособного инстанса на ПРОМ. Это еще и периодические бэкапы, откаты на резервную копию, начальное заполнение БД данными, заполнение "горячего" кэша, выбор нового master если старому плохо (leader election), тонкие настройки репликации и многое другое, чего я просто не знаю. А знают - хорошие DBA. Т.е. получается даже если мы поместим обычную СУБД в облако - DBA все равно нужен. Причем DBA, умеющий в облако, а это, кажется, редкая птица)
Т.е. все плохо? И снова нет. Если есть потребность отдать БД "на аутсорс" в облако, то выход - использование хранилищ от облачных провайдеров, спроектированных для работы в облаке. Там все вышеописанные тонкости будут учтены. Примеры:
1) Amazon Aurora https://habr.com/ru/companies/oleg-bunin/articles/471686/
2) YDB https://cloud.yandex.ru/ru/services/ydb
3) Azure Cosmos DB for PostgreSQL https://learn.microsoft.com/en-us/azure/cosmos-db/postgresql/introduction
Ну или хотя бы использование заточенных под работу в облаке СУБД. Вот пара примеров, первыми попавшихся мне на глаза:
1) Tarantool https://habr.com/ru/companies/vk/articles/533308/
2) CockroachDB https://www.cockroachlabs.com/docs/v23.2/deploy-cockroachdb-with-kubernetes
Как можно заметить, в обоих случаях есть специальный оператор k8s для управления кластером.
P.S. Тема сложная, интересная, поэтому думаю это не последняя статья.
#k8s #storage #cloud #rdbms
Есть такой интересный вопрос - можно ли поместить СУБД в облако?
Если отвечать на него строго технически - да, можно, для этого в k8s есть специальные типы объектов - StatefulSet https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/ и PersistentVolume
https://kubernetes.io/docs/concepts/storage/persistent-volumes/
которые обеспечивают ряд требуемых для СУБД характеристик:
1) подключенное хранилище не удаляется при каждой остановке пода
2) экземпляр StatefulSet имеет постоянное имя
3) процедура масштабирования StatefulSet в обе стороны последовательна - поды добавляются\удаляются по одному
Более того, в документации кубера есть пример с раскатыванием MySQL https://kubernetes.io/docs/tasks/run-application/run-replicated-stateful-application
Причем с возможностью автоматического масштабирования на чтение. Пример на самом деле меня впечатлил: сотня строк манифестов yaml - и БД уезжает в облако.
Так ли все хорошо?
Конечно же нет)
Для начала я бы задал типичный "менеджерский" вопрос - какую задачу решаем?
Первый момент - горизонтальное масштабирование на чтение можно обеспечить для любой СУБД. Как в облаке, так и без облака. На запись - только для NoSQL хранилищ с поддержкой шардирования.
Второй момент: сопровождение СУБД - это не просто гарантия наличия работоспособного инстанса на ПРОМ. Это еще и периодические бэкапы, откаты на резервную копию, начальное заполнение БД данными, заполнение "горячего" кэша, выбор нового master если старому плохо (leader election), тонкие настройки репликации и многое другое, чего я просто не знаю. А знают - хорошие DBA. Т.е. получается даже если мы поместим обычную СУБД в облако - DBA все равно нужен. Причем DBA, умеющий в облако, а это, кажется, редкая птица)
Т.е. все плохо? И снова нет. Если есть потребность отдать БД "на аутсорс" в облако, то выход - использование хранилищ от облачных провайдеров, спроектированных для работы в облаке. Там все вышеописанные тонкости будут учтены. Примеры:
1) Amazon Aurora https://habr.com/ru/companies/oleg-bunin/articles/471686/
2) YDB https://cloud.yandex.ru/ru/services/ydb
3) Azure Cosmos DB for PostgreSQL https://learn.microsoft.com/en-us/azure/cosmos-db/postgresql/introduction
Ну или хотя бы использование заточенных под работу в облаке СУБД. Вот пара примеров, первыми попавшихся мне на глаза:
1) Tarantool https://habr.com/ru/companies/vk/articles/533308/
2) CockroachDB https://www.cockroachlabs.com/docs/v23.2/deploy-cockroachdb-with-kubernetes
Как можно заметить, в обоих случаях есть специальный оператор k8s для управления кластером.
P.S. Тема сложная, интересная, поэтому думаю это не последняя статья.
#k8s #storage #cloud #rdbms
Kubernetes
StatefulSets
A StatefulSet runs a group of Pods, and maintains a sticky identity for each of those Pods. This is useful for managing applications that need persistent storage or a stable, unique network identity.
Всем привет!
Есть интересная тема - инструменты сборки для JVM проектов. А в рамках нее другая горячая тема - управление конфликтами зависимостей. Когда в проект подтягивается, как правило транзитивно, две версии одной и той же зависимости. А должна остаться только одна)
Отличное сравнение 3 систем сборки по управлению конфликтами зависимостей еще 10+ лет назад проведено в этой статье: https://habr.com/ru/companies/jugru/articles/191246/
Вывод из статьи - в Maven все сделано, скажет так, странно)))
Приходится явно указывать нужную версию каждой конфликтной зависимости в проекте.
Первый вопрос, который приходит на ум - зачем в Maven так сделали и когда собираются исправлять.
Ответ тут - https://stackoverflow.com/questions/34201120/maven-set-dependency-mediation-strategy-to-newest-rather-than-nearest
Спойлер - исправлять не собираются, считают, что так сборка будет более предсказуемой и повторяющейся. Т.е. описанный выше подход - запускай приложение, находи конфликты в runtime и указывай явно версию в своем модуле - считается правильным. Но есть лайфхак - см. ответ на stackoverflow.
Ну а чтобы найти версии проблемной зависимости - нужен mvn dependency:tree. О его "секретных" (на самом деле полезных) ключах этой таски Maven можно почитать тут https://www.digitalocean.com/community/tutorials/maven-dependency-tree-resolving-conflicts
Ну и если хочется копнуть глубже, например понять, как разрешается конфликт scope-ов зависимости или узнать про то, как разработчик библиотеки может уменьшить возможность появления конфликта (optional) - см. главный источник истины по Maven - его документацию https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
#maven #gradle #java #buildtool #dependency_management
Есть интересная тема - инструменты сборки для JVM проектов. А в рамках нее другая горячая тема - управление конфликтами зависимостей. Когда в проект подтягивается, как правило транзитивно, две версии одной и той же зависимости. А должна остаться только одна)
Отличное сравнение 3 систем сборки по управлению конфликтами зависимостей еще 10+ лет назад проведено в этой статье: https://habr.com/ru/companies/jugru/articles/191246/
Вывод из статьи - в Maven все сделано, скажет так, странно)))
Приходится явно указывать нужную версию каждой конфликтной зависимости в проекте.
Первый вопрос, который приходит на ум - зачем в Maven так сделали и когда собираются исправлять.
Ответ тут - https://stackoverflow.com/questions/34201120/maven-set-dependency-mediation-strategy-to-newest-rather-than-nearest
Спойлер - исправлять не собираются, считают, что так сборка будет более предсказуемой и повторяющейся. Т.е. описанный выше подход - запускай приложение, находи конфликты в runtime и указывай явно версию в своем модуле - считается правильным. Но есть лайфхак - см. ответ на stackoverflow.
Ну а чтобы найти версии проблемной зависимости - нужен mvn dependency:tree. О его "секретных" (на самом деле полезных) ключах этой таски Maven можно почитать тут https://www.digitalocean.com/community/tutorials/maven-dependency-tree-resolving-conflicts
Ну и если хочется копнуть глубже, например понять, как разрешается конфликт scope-ов зависимости или узнать про то, как разработчик библиотеки может уменьшить возможность появления конфликта (optional) - см. главный источник истины по Maven - его документацию https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
#maven #gradle #java #buildtool #dependency_management
Хабр
Разрешение конфликтов в транзитивных зависимостях — Хороший, Плохой, Злой
Вместо предисловия В ближайшую субботу мы с EvgenyBorisov будем выступать в Питере на JUG.ru . Будет много веселого трэша и интересной инфы (иногда не разберешь, где проходит граница), и одно из моих...
Всем привет!
Вдогонку ко вчерашней теме про управление зависимостями.
В Maven есть две фичи, смягчающие боль по управлению зависимостями:
1) bom - Bill Of material - pom-ник, объявляющий версии протестированного и гарантированного рабочего набора обязательных зависимостей, например, библиотеки Spring Security
2) dependencyManagemenet - возможность в одном месте, как правило это корневой pom, объявить все версии используемых в проекте библиотек. Туда же можно подключать уже готовые bom-ы. После этого задача поднятия версии какой-то зависимости по всему многомодульному проекту упрощается
Есть ли что-то подобное в Gradle?
Да, есть.
Вот тут описывается как "сэмулировать" bom в Gradle - https://habr.com/ru/articles/784784/
Ключевые слова platform и constraints https://docs.gradle.org/current/userguide/dependency_constraints.html
Почему я говорю сэмулировать: если посмотреть на структуру bom - это типичный Maven xml файл. Gradle публикует bom в двух форматах - maven для совместимости и свой json, вот пример https://repo1.maven.org/maven2/io/github/mfvanek/pg-index-health-bom/0.10.2/
Но на самом деле Gradle умеет чуть больше - есть такая штука, как catalog - по сути позволяющая структурировать зависимости в древовидную структуру и дать имя-ссылку каждому уровню. См. https://docs.gradle.org/current/userguide/platforms.html Причем объявлять завимости можно как в build.gradle, так и в отдельном toml файле. Каталог можно использовать сам по себе - как набор версий, так и ограничивать с помощью него версии транзитивных зависимостей - через те же constraints и platform.
#gradle #maven #depenedency_management #buildtool
Вдогонку ко вчерашней теме про управление зависимостями.
В Maven есть две фичи, смягчающие боль по управлению зависимостями:
1) bom - Bill Of material - pom-ник, объявляющий версии протестированного и гарантированного рабочего набора обязательных зависимостей, например, библиотеки Spring Security
2) dependencyManagemenet - возможность в одном месте, как правило это корневой pom, объявить все версии используемых в проекте библиотек. Туда же можно подключать уже готовые bom-ы. После этого задача поднятия версии какой-то зависимости по всему многомодульному проекту упрощается
Есть ли что-то подобное в Gradle?
Да, есть.
Вот тут описывается как "сэмулировать" bom в Gradle - https://habr.com/ru/articles/784784/
Ключевые слова platform и constraints https://docs.gradle.org/current/userguide/dependency_constraints.html
Почему я говорю сэмулировать: если посмотреть на структуру bom - это типичный Maven xml файл. Gradle публикует bom в двух форматах - maven для совместимости и свой json, вот пример https://repo1.maven.org/maven2/io/github/mfvanek/pg-index-health-bom/0.10.2/
Но на самом деле Gradle умеет чуть больше - есть такая штука, как catalog - по сути позволяющая структурировать зависимости в древовидную структуру и дать имя-ссылку каждому уровню. См. https://docs.gradle.org/current/userguide/platforms.html Причем объявлять завимости можно как в build.gradle, так и в отдельном toml файле. Каталог можно использовать сам по себе - как набор версий, так и ограничивать с помощью него версии транзитивных зависимостей - через те же constraints и platform.
#gradle #maven #depenedency_management #buildtool
Хабр
Создание и использование BOM в Gradle
Привет Хабр! В каждой компании (а если она крупная, то, скорее всего, в каждом подразделении) должна быть выстроена культура использования BOM ( bill of materials ) для управления версиями...
Всем привет!
Наверное вы слышали про такой стандарт API как GraphQL. Если посмотреть на главную страницу их сайта https://graphql.org/, то там бросается в глаза фраза: "Evolve your API without versions".
Если воспринимать ее буквально, то можно подумать: "О, круто, API без версионирования! А что так можно было?)"
Но как это обычно бывает в разработке - не все так просто.
Если подумать - API без версионирования и без сопутствующих ему проблем, в частности несовместимых изменений, может быть только в том случае, если в API вообще нет обязательных полей. Но полезность такого API стремится к нулю. А точнее это уже не API, а что-то похоже на поиск Google или Yandex или общение с ChatGPT.
В GraphQL конечно же обязательные поля есть. Единственный момент - по умолчанию все поля не обязательны.
А если подумать еще - есть еще один способ. Завязаться на какой-то стандарт уровня HTTP, HTML или SWIFT, у которого так много потребителей, что волей неволей придется поддерживать обратную совместимость. Матерится сквозь зубы, но поддерживать) И то, даже в таких областях появляются новые версии API.
Плюс можно добавить уровень API шлюза - наружу выдаем API по стандарт, внутри - свое, которое может меняться свободно.
Но напрямую к GraphQL этот кейс не относится, это можно сделать и с REST, и с JSON-RPC.
Но если вчитаться в документацию GraphQL внимательнее, то видно, что авторы предлагают другое - эволюцию API мелкими шагами без явного задания версий.
https://principledgraphql.com/agility/#5-use-an-agile-approach-to-schema-development
Agile в деле построения API.
По сути это старый добрый принцип:
1) добавляем новый метод в API
2) старый объявляем deprecated
3) уведомляем об этом потребителей, не забывая про дату вывода из эксплуатации
4) когда придет время удаляем старое API
Profit!
В GraphQL выглядит это вот так:
type Account {
surname: String! @deprecated(reason: "Use
personSurname: String
}
В чем тут могут быть проблемы:
1) не факт, что потребители вовремя обновятся. Да, deprecated на уровне API лучше, чем рассылка потребителям или страничка в сети, но это не панацея. К слову, OpenAPI тоже так умеет.
2) да, контролировать потребителей на уровне отдельного deprecated поля в GraphQL гораздо проще: возможность на клиенте указывать только нужные поля - это наверное главная фишка GraphQL. Но не все потребители будут так делать. Некоторые - сознательно, нарушая конвенцию использования GraphQL, некоторые - случайно, просто забыв убрать лишние поля
3) если работать до последнего потребителя - API быстро превратится в помойку
4) а главное: если заводить множество мелких изменений в API - каждый спринт по изменению - со временем очень сложно станет этим управлять. Да, есть инструменты, облегчающие управление - https://github.com/kamilkisiela/graphql-inspector Да, нужна четкая политика по работе с изменениями API. Но у меня есть сомнения, будет ли это все работать при непрерывном потоке изменений в большой организации без введения новых версий. Как и Agile в целом такой подход требует ответственности от команды и также плохо масштабируется.
Ну и последнее. Да, ничего для создания версий в GraphQL нет. Но никто не мешает развернуть рядом endpoint и назвать его graphql/v2. Или в схему к полю xyz добавить поле xyzV2 )))
#api #graphql #versioning
Наверное вы слышали про такой стандарт API как GraphQL. Если посмотреть на главную страницу их сайта https://graphql.org/, то там бросается в глаза фраза: "Evolve your API without versions".
Если воспринимать ее буквально, то можно подумать: "О, круто, API без версионирования! А что так можно было?)"
Но как это обычно бывает в разработке - не все так просто.
Если подумать - API без версионирования и без сопутствующих ему проблем, в частности несовместимых изменений, может быть только в том случае, если в API вообще нет обязательных полей. Но полезность такого API стремится к нулю. А точнее это уже не API, а что-то похоже на поиск Google или Yandex или общение с ChatGPT.
В GraphQL конечно же обязательные поля есть. Единственный момент - по умолчанию все поля не обязательны.
А если подумать еще - есть еще один способ. Завязаться на какой-то стандарт уровня HTTP, HTML или SWIFT, у которого так много потребителей, что волей неволей придется поддерживать обратную совместимость. Матерится сквозь зубы, но поддерживать) И то, даже в таких областях появляются новые версии API.
Плюс можно добавить уровень API шлюза - наружу выдаем API по стандарт, внутри - свое, которое может меняться свободно.
Но напрямую к GraphQL этот кейс не относится, это можно сделать и с REST, и с JSON-RPC.
Но если вчитаться в документацию GraphQL внимательнее, то видно, что авторы предлагают другое - эволюцию API мелкими шагами без явного задания версий.
https://principledgraphql.com/agility/#5-use-an-agile-approach-to-schema-development
Agile в деле построения API.
По сути это старый добрый принцип:
1) добавляем новый метод в API
2) старый объявляем deprecated
3) уведомляем об этом потребителей, не забывая про дату вывода из эксплуатации
4) когда придет время удаляем старое API
Profit!
В GraphQL выглядит это вот так:
type Account {
surname: String! @deprecated(reason: "Use
personSurname
")personSurname: String
}
В чем тут могут быть проблемы:
1) не факт, что потребители вовремя обновятся. Да, deprecated на уровне API лучше, чем рассылка потребителям или страничка в сети, но это не панацея. К слову, OpenAPI тоже так умеет.
2) да, контролировать потребителей на уровне отдельного deprecated поля в GraphQL гораздо проще: возможность на клиенте указывать только нужные поля - это наверное главная фишка GraphQL. Но не все потребители будут так делать. Некоторые - сознательно, нарушая конвенцию использования GraphQL, некоторые - случайно, просто забыв убрать лишние поля
3) если работать до последнего потребителя - API быстро превратится в помойку
4) а главное: если заводить множество мелких изменений в API - каждый спринт по изменению - со временем очень сложно станет этим управлять. Да, есть инструменты, облегчающие управление - https://github.com/kamilkisiela/graphql-inspector Да, нужна четкая политика по работе с изменениями API. Но у меня есть сомнения, будет ли это все работать при непрерывном потоке изменений в большой организации без введения новых версий. Как и Agile в целом такой подход требует ответственности от команды и также плохо масштабируется.
Ну и последнее. Да, ничего для создания версий в GraphQL нет. Но никто не мешает развернуть рядом endpoint и назвать его graphql/v2. Или в схему к полю xyz добавить поле xyzV2 )))
#api #graphql #versioning
graphql.org
GraphQL | A query language for your API
Всем привет!
Самая крутая фича GraphQL - это возможность явного указания какие данные нужны клиенту.
Причем фильтровать можно на любом уровне вложенности объектов.
И к тому же фильтровать не только по возвращаемым полям, но и по списку записей - аналог WHERE в SQL.
Пример запроса:
{
authors(surname: "Пушкин") {
name,
surname,
books(year: "1831")) {
title,
genre,
year
}
}
}
На стороне сервера для каждого объекта в запросе - в моем примере Author и Book - можно написать свой fetcher, независимо вытаскивающий данные из хранилища.
А вишенка на торте - с помощью Federation https://netflix.github.io/dgs/advanced/federated-testing/ можно децентрализовать схему, расположив fetchers в разных микросервисах.
Но главный плюс также является и главной потенциальной проблемой.
GraphQL подталкивает к тому, чтобы был один endpoint, через который можно получить все данные.
А если потребители захотят получить все?)
Встают вопросы:
1) разграничения доступа. В целом решается интеграцией со Spring Security https://netflix.github.io/dgs/advanced/security/ Можно расставить аннотации @Secured над каждым объектом. Но я вижу больше рисков по сравнению с специальным REST endpoint, "заточенным" под определенный набор данных.
2) производительности - ведь одним запросом к GraphQL сервису в теории можно вытащить все содержимое БД. А скорее получить проблему N+1 и подвесить БД). Авторы естественно знают об этой проблеме https://netflix.github.io/dgs/data-loaders/ и предлагают решение: batching и кэширование. Но решение не коробочное, требуется проектирование
P.S. Еще одна крутая фича - graphiql - интерактивная веб-консоль для построения запросов, включенная по умолчанию https://github.com/graphql/graphiql C auto-completion.
Ну и конечно возможность подписки на события как часть протокола GraphQL. Реализуется как правило через WebsSocket https://netflix.github.io/dgs/advanced/subscriptions/
#graphql #api
Самая крутая фича GraphQL - это возможность явного указания какие данные нужны клиенту.
Причем фильтровать можно на любом уровне вложенности объектов.
И к тому же фильтровать не только по возвращаемым полям, но и по списку записей - аналог WHERE в SQL.
Пример запроса:
{
authors(surname: "Пушкин") {
name,
surname,
books(year: "1831")) {
title,
genre,
year
}
}
}
На стороне сервера для каждого объекта в запросе - в моем примере Author и Book - можно написать свой fetcher, независимо вытаскивающий данные из хранилища.
А вишенка на торте - с помощью Federation https://netflix.github.io/dgs/advanced/federated-testing/ можно децентрализовать схему, расположив fetchers в разных микросервисах.
Но главный плюс также является и главной потенциальной проблемой.
GraphQL подталкивает к тому, чтобы был один endpoint, через который можно получить все данные.
А если потребители захотят получить все?)
Встают вопросы:
1) разграничения доступа. В целом решается интеграцией со Spring Security https://netflix.github.io/dgs/advanced/security/ Можно расставить аннотации @Secured над каждым объектом. Но я вижу больше рисков по сравнению с специальным REST endpoint, "заточенным" под определенный набор данных.
2) производительности - ведь одним запросом к GraphQL сервису в теории можно вытащить все содержимое БД. А скорее получить проблему N+1 и подвесить БД). Авторы естественно знают об этой проблеме https://netflix.github.io/dgs/data-loaders/ и предлагают решение: batching и кэширование. Но решение не коробочное, требуется проектирование
P.S. Еще одна крутая фича - graphiql - интерактивная веб-консоль для построения запросов, включенная по умолчанию https://github.com/graphql/graphiql C auto-completion.
Ну и конечно возможность подписки на события как часть протокола GraphQL. Реализуется как правило через WebsSocket https://netflix.github.io/dgs/advanced/subscriptions/
#graphql #api
Всем привет!
При чтении одной из статей наткнулся на такую штуку, как Oracle Autonomous Database. Загуглил. Первая ссылка конечно же на сайт Oracle https://www.oracle.com/autonomous-database/
Там вот такое описание:
"Oracle Autonomous Database is a fully automated service that makes it easy for all organizations to develop and deploy application workloads, regardless of complexity, scale, or criticality. The service’s converged engine supports diverse data types, simplifying application development and deployment from modeling and coding to ETL, database optimization, and data analysis. ..."
Все же сразу понятно?))))
А вот что пишет Гугл в быстрых подсказках:
"An autonomous database is a cloud database that uses machine learning to automate database tuning, security, backups, updates, and other routine management tasks traditionally performed by DBAs. Unlike a conventional database, an autonomous database performs all these tasks and more without human intervention."
Яндекс кстати "залажал" - выдал русский перевод с сайта Oracle.
Вопрос - что должно произойти, чтобы enterprise разработчики стали описывать свои технологии нормально?) Широкое внедрение open-source, похоже, не помогло. У многих enterprise уровень воды по прежнему сравним с типичными CEO оптимизированными сайтами, где ответ на простой вопрос скрывается где-то во 3-5)))) главе. Или вообще отсутствует. Так и растет популярность ChatGPT...
#blood_enterpirise #oracle
При чтении одной из статей наткнулся на такую штуку, как Oracle Autonomous Database. Загуглил. Первая ссылка конечно же на сайт Oracle https://www.oracle.com/autonomous-database/
Там вот такое описание:
"Oracle Autonomous Database is a fully automated service that makes it easy for all organizations to develop and deploy application workloads, regardless of complexity, scale, or criticality. The service’s converged engine supports diverse data types, simplifying application development and deployment from modeling and coding to ETL, database optimization, and data analysis. ..."
Все же сразу понятно?))))
А вот что пишет Гугл в быстрых подсказках:
"An autonomous database is a cloud database that uses machine learning to automate database tuning, security, backups, updates, and other routine management tasks traditionally performed by DBAs. Unlike a conventional database, an autonomous database performs all these tasks and more without human intervention."
Яндекс кстати "залажал" - выдал русский перевод с сайта Oracle.
Вопрос - что должно произойти, чтобы enterprise разработчики стали описывать свои технологии нормально?) Широкое внедрение open-source, похоже, не помогло. У многих enterprise уровень воды по прежнему сравним с типичными CEO оптимизированными сайтами, где ответ на простой вопрос скрывается где-то во 3-5)))) главе. Или вообще отсутствует. Так и растет популярность ChatGPT...
#blood_enterpirise #oracle
Oracle
Autonomous Data Management
Oracle Autonomous Database combines the flexibility of cloud with the power of machine learning to deliver data management as a service.
Всем привет!
Нашел хорошую статью о том, как совместить тестирование Spring контроллеров и один из самых известных фреймворков для тестирования REST - Rest Assured. https://www.baeldung.com/spring-mock-mvc-rest-assured
Кстати, в начале статьи есть ссылка на пример использования чистого Spring MVC Test, если кто его не использовал - можете сравнить синтаксис.
Еще статья хороша тем, что четко разделяет модульные и интеграционные тесты. И я бы разделил точно также) Я иногда задаю вопрос о видах тестов на интервью, ответ мне не всегда нравится. Для ленивых, вкратце - интеграционным тест можно считать, если появляется сеть - открывается порт, вызывается другой процесс, внешнее хранилище, пусть даже и в embedded варианте. Хотя справедливости ради - вопрос холиварный, из-за того, что много пограничных случаев.
#unittests #spring #rest #integration_tests #interview_question
Нашел хорошую статью о том, как совместить тестирование Spring контроллеров и один из самых известных фреймворков для тестирования REST - Rest Assured. https://www.baeldung.com/spring-mock-mvc-rest-assured
Кстати, в начале статьи есть ссылка на пример использования чистого Spring MVC Test, если кто его не использовал - можете сравнить синтаксис.
Еще статья хороша тем, что четко разделяет модульные и интеграционные тесты. И я бы разделил точно также) Я иногда задаю вопрос о видах тестов на интервью, ответ мне не всегда нравится. Для ленивых, вкратце - интеграционным тест можно считать, если появляется сеть - открывается порт, вызывается другой процесс, внешнее хранилище, пусть даже и в embedded варианте. Хотя справедливости ради - вопрос холиварный, из-за того, что много пограничных случаев.
#unittests #spring #rest #integration_tests #interview_question
Baeldung
REST-assured Support for Spring MockMvc | Baeldung
Learn how to test Spring REST controllers using the RestAssuredMockMvc API from REST-assured.
Всем привет!
Наверное все здесь знают, что такое UUID. Universally Unique IDentifier. Можно использовать как искусственный ключ. С высокой точностью обеспечивает уникальность, хотя и не 100%. Казалось бы, о чем здесь можно рассказывать. Ну и UUID и UUID.
А если я скажу, что недавно вышла 7-я (!) версия стандарта?) Для меня это было сюрпризом.
Вот описание первых 5 версий: https://habr.com/ru/companies/vk/articles/522094/
Вот - какие проблемы решает 7-й https://www.pvsm.ru/sistemnoe-programmirovanie/367012
А вот генератор разных версий с кратким описанием каждой: https://idtools.co/uuid/v7
Если вкратце про суть проблемы - UUID часто используют в БД как ключ. Но при таком использовании у него есть один большой минус - значения UUID не возрастают монолитно, как, например, обычный инкремент. Где это может быть полезно - сортировка и партиционирование таблиц.
Что интересно - в первой версии UUID было зашито время, а время - это тоже счетчик, в формате "с начала эпохи" или Unix time. Но в первой версии время хранилось в 2 разных частях UUID, причем еще и в перевернутом виде.
А 6-я версия - легкая модификация 1-й, где первый блок, содержащий время, хранят в нормальном формате и по таким UUID возможна сортировка.
#uuid #rdbms
Наверное все здесь знают, что такое UUID. Universally Unique IDentifier. Можно использовать как искусственный ключ. С высокой точностью обеспечивает уникальность, хотя и не 100%. Казалось бы, о чем здесь можно рассказывать. Ну и UUID и UUID.
А если я скажу, что недавно вышла 7-я (!) версия стандарта?) Для меня это было сюрпризом.
Вот описание первых 5 версий: https://habr.com/ru/companies/vk/articles/522094/
Вот - какие проблемы решает 7-й https://www.pvsm.ru/sistemnoe-programmirovanie/367012
А вот генератор разных версий с кратким описанием каждой: https://idtools.co/uuid/v7
Если вкратце про суть проблемы - UUID часто используют в БД как ключ. Но при таком использовании у него есть один большой минус - значения UUID не возрастают монолитно, как, например, обычный инкремент. Где это может быть полезно - сортировка и партиционирование таблиц.
Что интересно - в первой версии UUID было зашито время, а время - это тоже счетчик, в формате "с начала эпохи" или Unix time. Но в первой версии время хранилось в 2 разных частях UUID, причем еще и в перевернутом виде.
А 6-я версия - легкая модификация 1-й, где первый блок, содержащий время, хранят в нормальном формате и по таким UUID возможна сортировка.
#uuid #rdbms
Хабр
Как генерируются UUID
Вы наверняка уже использовали в своих проектах UUID и полагали, что они уникальны. Давайте рассмотрим основные аспекты реализации и разберёмся, почему UUID практически уникальны, поскольку существует...
Всем привет!
Микросервисная архитектура, которая становится все более популярной, требует хранения кода каждого сервиса в отдельном репозитории. На всякий пожарный - про остальные требования к микросервисам можно почитать тут https://t.me/javaKotlinDevOps/55
Бонусом мы получаем "штатную" работы IDE, pipeline, механизмов код-ревью. Микросервис подразумевает небольшой объём кода, т.е. все инструменты будут отрабатывать достаточно быстро, с меньшей вероятностью тормозить или падать, меньше вероятность конфликтов merge и т.д.
Зачем же тогда могут понадобится гигантские монорепы?
А ведь примеров хватает:
Яндекс https://habr.com/ru/companies/yandex/articles/469021/
Гугл https://qeunit.com/blog/how-google-does-monorepo/
Microsoft Windows https://habr.com/ru/articles/795635/
И даже Юла: https://habr.com/ru/companies/oleg-bunin/articles/531632/
Отдельно я бы выделил три типовых кейса, не относящиеся к микросервисам:
1) собственно монолит. И причина понятна - странно части монолита собирать из разных репозиториев. Релизный цикл, pipeline все равно же общие
2) игры. Тоже по сути отдельный вид монолита - огромные размеры репо, особенность: основной объем занимают бинарные данные: текстуры, картинки, видео...
3) большие мобильные приложения, SuperApp или стремящиеся к ним. Тоже по сути отдельный случай монолита.
Но в списке выше есть и микросервисы, зачем им лезть в монорепы? Суммируя, можно выделить такие причины:
1) проще контроль над своевременностью обновления библиотек
2) возможность одним PR занести кросс-сервисную фичу. Кстати, полезная штука
3) обучение новичков и обмен знаниями на примерах из других сервисов. Кажется, что это можно сделать и с разными репо, но в монорепе, конечно, удобнее
4) облегчение работы с общим кодом - не надо подключать новые модули явно в каждый сервис, просто работаем с тем, что есть в develop. Опять же все ошибки при выпуске новой версии общего кода ловятся быстрее, т.к. все тесты в одном месте. Конечно тесты, а точнее достаточное тестовое покрытие, должно быть) Рефакторинг, застрагивающий все части системы, как правило связанный с изменением общего API, также проводить проще
5) легче обеспечить унификацию требований к коду. Тоже - можно решить на уровне pipeline и commit hook, но в одном репо проще
6) т.к. модули в монорепо скорее всего работают вместе, а иначе зачем их код хранится вместе - с монорепо можно развернуть тестовый стенд проще, чем с отдельными микросервисами
Что касается минусов - про то как их побороть, можно глянуть статьи выше. Особенно полезна статья про Microsoft, содержащая технические советы по обслуживанию репо на уровне git-а. Часть я знал и ранее, и даже использовал, часть для меня стало сюрпризом. Что особенно важно - все доработки из своего форка git Microsoft портировала в master git. Вот краткий список советов:
1) sparse checkout - выкачивание только нужных папок
2) shallow copy - выкачивание ограниченного числа версии из истории изменений, как правило, только последней
3) клонирование без blob (--filter=blob: none) В blob хранится содержимое файлов. Ясно, что без содержимого файлов разработка невозможна, но в этом режиме git во-первых подкачивает blob для последней версии, а во-вторых - будет подкачивать необходимые ему файлы по требованию
4) также может быть полезно клонирование без checkout, опция --no-checkout, т.е. без копирования собственно файлов в рабочий каталог. Так мы сможем избежать случайного копирования всех файлов до того, как будет проведена фильтрация
5) запуск git maintenance в фоне - обновление графа коммитов, ускоряет выполнение некоторых команд git
6) фоновый монитор файловой системы, настройка git config core.fsmonitor true. Слушает уведомления об изменений файлов в каталоге с исходниками, поэтому git status отрабатывает быстрее.
Более того, в состав Git есть отдельная утилита scalar, из коробки делающая многое из перечисленных выше пунктов.
Итоги: если можно обойтись без монорепо - так и нужно делать. Но если все же решили его использовать - боль можно облегчить)
#git #microservices #monorepo
Микросервисная архитектура, которая становится все более популярной, требует хранения кода каждого сервиса в отдельном репозитории. На всякий пожарный - про остальные требования к микросервисам можно почитать тут https://t.me/javaKotlinDevOps/55
Бонусом мы получаем "штатную" работы IDE, pipeline, механизмов код-ревью. Микросервис подразумевает небольшой объём кода, т.е. все инструменты будут отрабатывать достаточно быстро, с меньшей вероятностью тормозить или падать, меньше вероятность конфликтов merge и т.д.
Зачем же тогда могут понадобится гигантские монорепы?
А ведь примеров хватает:
Яндекс https://habr.com/ru/companies/yandex/articles/469021/
Гугл https://qeunit.com/blog/how-google-does-monorepo/
Microsoft Windows https://habr.com/ru/articles/795635/
И даже Юла: https://habr.com/ru/companies/oleg-bunin/articles/531632/
Отдельно я бы выделил три типовых кейса, не относящиеся к микросервисам:
1) собственно монолит. И причина понятна - странно части монолита собирать из разных репозиториев. Релизный цикл, pipeline все равно же общие
2) игры. Тоже по сути отдельный вид монолита - огромные размеры репо, особенность: основной объем занимают бинарные данные: текстуры, картинки, видео...
3) большие мобильные приложения, SuperApp или стремящиеся к ним. Тоже по сути отдельный случай монолита.
Но в списке выше есть и микросервисы, зачем им лезть в монорепы? Суммируя, можно выделить такие причины:
1) проще контроль над своевременностью обновления библиотек
2) возможность одним PR занести кросс-сервисную фичу. Кстати, полезная штука
3) обучение новичков и обмен знаниями на примерах из других сервисов. Кажется, что это можно сделать и с разными репо, но в монорепе, конечно, удобнее
4) облегчение работы с общим кодом - не надо подключать новые модули явно в каждый сервис, просто работаем с тем, что есть в develop. Опять же все ошибки при выпуске новой версии общего кода ловятся быстрее, т.к. все тесты в одном месте. Конечно тесты, а точнее достаточное тестовое покрытие, должно быть) Рефакторинг, застрагивающий все части системы, как правило связанный с изменением общего API, также проводить проще
5) легче обеспечить унификацию требований к коду. Тоже - можно решить на уровне pipeline и commit hook, но в одном репо проще
6) т.к. модули в монорепо скорее всего работают вместе, а иначе зачем их код хранится вместе - с монорепо можно развернуть тестовый стенд проще, чем с отдельными микросервисами
Что касается минусов - про то как их побороть, можно глянуть статьи выше. Особенно полезна статья про Microsoft, содержащая технические советы по обслуживанию репо на уровне git-а. Часть я знал и ранее, и даже использовал, часть для меня стало сюрпризом. Что особенно важно - все доработки из своего форка git Microsoft портировала в master git. Вот краткий список советов:
1) sparse checkout - выкачивание только нужных папок
2) shallow copy - выкачивание ограниченного числа версии из истории изменений, как правило, только последней
3) клонирование без blob (--filter=blob: none) В blob хранится содержимое файлов. Ясно, что без содержимого файлов разработка невозможна, но в этом режиме git во-первых подкачивает blob для последней версии, а во-вторых - будет подкачивать необходимые ему файлы по требованию
4) также может быть полезно клонирование без checkout, опция --no-checkout, т.е. без копирования собственно файлов в рабочий каталог. Так мы сможем избежать случайного копирования всех файлов до того, как будет проведена фильтрация
5) запуск git maintenance в фоне - обновление графа коммитов, ускоряет выполнение некоторых команд git
6) фоновый монитор файловой системы, настройка git config core.fsmonitor true. Слушает уведомления об изменений файлов в каталоге с исходниками, поэтому git status отрабатывает быстрее.
Более того, в состав Git есть отдельная утилита scalar, из коробки делающая многое из перечисленных выше пунктов.
Итоги: если можно обойтись без монорепо - так и нужно делать. Но если все же решили его использовать - боль можно облегчить)
#git #microservices #monorepo
Telegram
(java || kotlin) && devOps
Всем привет!
Поговорим про микросервисы. Статей будет несколько, от плюсов и минусов до саги и прочих паттернов.
Для начала что такое микросервис. Я дам определение в виде набора обязательных признаков. Обязательны все из них.
1) одна команда
2) отдельная…
Поговорим про микросервисы. Статей будет несколько, от плюсов и минусов до саги и прочих паттернов.
Для начала что такое микросервис. Я дам определение в виде набора обязательных признаков. Обязательны все из них.
1) одна команда
2) отдельная…
Всем привет!
Нашел вот такую интересную штуку для работы с git - https://gitbutler.com/ По сути ребята взяли идею IDEA ))) с change list-ами, и сделали из change list полноценную ветку. Ну как полноценную - виртуальную, git про них не знает, вся информация о такой ветке хранится локально. change list-у можно дать название и закоммитить отдельно, а в виртуальной ветке, как и в обычной, кроме того можно делать коммиты, а также объединять, переименовывать и откатывать их. Вот видео с основными фишками https://www.youtube.com/watch?v=PWc4meBj4jo
Цель утилиты - одновременная работа над несколькими ветками. Причем судя по видео создание новых веток и переключение между ними реально быстрое, у меня даже иногда возникала мысль - а не ускорили ли они видео) Ну и надо сказать, утилита пропагандирует минимально возможные изменения в коммите и в ветках, в пределе - одно изменение = один коммит, что также способствует скорости работы. В этом она мне напомнила https://darcs.net/Features, где тоже идет упор на то, что каждая строчка с изменением может стать отдельным коммитом. Но в отличие от Darcs GitButler полностью совместим с Git. И активно развивается.
Еще небольшая полезная плюшка - автоматическая генерация текста коммитов, то самое применение AI, о котором недавно писал.
Да, для индивидуальных пользователей утилита бесплатная.
Главное неудобство - нельзя работать с ветками в IDEA, т.к. git client, встроенный в IDEA, ничего не знает о виртуальных ветках.
Второй момент - пока доступно только для Mac и Linux, а так я бы попробовал(
#git
Нашел вот такую интересную штуку для работы с git - https://gitbutler.com/ По сути ребята взяли идею IDEA ))) с change list-ами, и сделали из change list полноценную ветку. Ну как полноценную - виртуальную, git про них не знает, вся информация о такой ветке хранится локально. change list-у можно дать название и закоммитить отдельно, а в виртуальной ветке, как и в обычной, кроме того можно делать коммиты, а также объединять, переименовывать и откатывать их. Вот видео с основными фишками https://www.youtube.com/watch?v=PWc4meBj4jo
Цель утилиты - одновременная работа над несколькими ветками. Причем судя по видео создание новых веток и переключение между ними реально быстрое, у меня даже иногда возникала мысль - а не ускорили ли они видео) Ну и надо сказать, утилита пропагандирует минимально возможные изменения в коммите и в ветках, в пределе - одно изменение = один коммит, что также способствует скорости работы. В этом она мне напомнила https://darcs.net/Features, где тоже идет упор на то, что каждая строчка с изменением может стать отдельным коммитом. Но в отличие от Darcs GitButler полностью совместим с Git. И активно развивается.
Еще небольшая полезная плюшка - автоматическая генерация текста коммитов, то самое применение AI, о котором недавно писал.
Да, для индивидуальных пользователей утилита бесплатная.
Главное неудобство - нельзя работать с ветками в IDEA, т.к. git client, встроенный в IDEA, ничего не знает о виртуальных ветках.
Второй момент - пока доступно только для Mac и Linux, а так я бы попробовал(
#git
GitButler
GitButler software development platform
Всем привет!
Интересно сравнить рейтинг языков программирования по поисковым запросам https://www.tiobe.com/tiobe-index/ и по коду на github https://innovationgraph.github.com/global-metrics/programming-languages
Что бросилось в глаза:
1) большего всего кода на JavaScript, хотя ищут информацию по нему существенно меньше. Аналогично по TypeScript, причем в поиске он явно в тени JavaScript. Что ж, это стандарт в вебе, никуда с подводной лодки не денешься)
2) Java, Kotlin - позиции примерно совпадают в обоих списках. Стабильность) Perl и PHP к слову тоже. Но если позиция Java меня радует, Kotlin - кажется должно быть выше, Perl - ну ок, позиция в районе 25 места, то к PHP и его стабильному месту в десятке вопросики... Хотя надо сказать, что именно в PHP я видел самые строгие требования к документации. Правда похоже никто из разработчиков их не читает)
3) позиции Go и Rust по поиску сильно выше, чем по коду. Разница в 10 позиций. Налицо рост популярности
4) но еще сильнее разрыв между поиском и кодов для Fortran и Cobol. Cobol так вообще по коду в топ 50 не входит, а ищут его неплохо, как Kotlin. Подозреваю, причина в том, что код лежит во внутренних репозиториях "кровавого enterprise") И пришла пора его интегрировать с AI)
5) у Ruby кода существенно больше, чем популярности в поиске, тоже разница порядка 10 позиций. Так что хоронить Ruby еще рано, но то, что он уже не модный - факт)
6) наблюдается взлет популярности в поиске С#
7) позиции C и C++ по коду поменьше, чем в поиске. Я бы предположил, что тут как в анекдоте: удар молотком - 1 рубль, знал куда ударить - 1000 рублей)
8) Swift давно обогнал Objective-C в поиске, но еще не обогнал по коду. Это основные языки для разработки iOS\MacOS если что
9) код на Delphi где-то спрятан... Не думаю, что Enterprise, скорее на компьютерах университетов и школ
10) довольно много кода в репо для Shell, Makefile, Dockerfile, CMake, Powershell что в целом объяснимо. Groovy тоже можно в эту категорию отнести - сборка и deploy.
#languages
Интересно сравнить рейтинг языков программирования по поисковым запросам https://www.tiobe.com/tiobe-index/ и по коду на github https://innovationgraph.github.com/global-metrics/programming-languages
Что бросилось в глаза:
1) большего всего кода на JavaScript, хотя ищут информацию по нему существенно меньше. Аналогично по TypeScript, причем в поиске он явно в тени JavaScript. Что ж, это стандарт в вебе, никуда с подводной лодки не денешься)
2) Java, Kotlin - позиции примерно совпадают в обоих списках. Стабильность) Perl и PHP к слову тоже. Но если позиция Java меня радует, Kotlin - кажется должно быть выше, Perl - ну ок, позиция в районе 25 места, то к PHP и его стабильному месту в десятке вопросики... Хотя надо сказать, что именно в PHP я видел самые строгие требования к документации. Правда похоже никто из разработчиков их не читает)
3) позиции Go и Rust по поиску сильно выше, чем по коду. Разница в 10 позиций. Налицо рост популярности
4) но еще сильнее разрыв между поиском и кодов для Fortran и Cobol. Cobol так вообще по коду в топ 50 не входит, а ищут его неплохо, как Kotlin. Подозреваю, причина в том, что код лежит во внутренних репозиториях "кровавого enterprise") И пришла пора его интегрировать с AI)
5) у Ruby кода существенно больше, чем популярности в поиске, тоже разница порядка 10 позиций. Так что хоронить Ruby еще рано, но то, что он уже не модный - факт)
6) наблюдается взлет популярности в поиске С#
7) позиции C и C++ по коду поменьше, чем в поиске. Я бы предположил, что тут как в анекдоте: удар молотком - 1 рубль, знал куда ударить - 1000 рублей)
8) Swift давно обогнал Objective-C в поиске, но еще не обогнал по коду. Это основные языки для разработки iOS\MacOS если что
9) код на Delphi где-то спрятан... Не думаю, что Enterprise, скорее на компьютерах университетов и школ
10) довольно много кода в репо для Shell, Makefile, Dockerfile, CMake, Powershell что в целом объяснимо. Groovy тоже можно в эту категорию отнести - сборка и deploy.
#languages
Github
GitHub Innovation Graph
Explore a universe of data about how the world is building software together on GitHub.
Всем привет!
Нашел хорошую статью-боль https://habr.com/ru/articles/739452/
Она как бы про DevOps, но на самом деле нет - точно такая же проблема есть у разработчиков, тестировщиков, сопровождения.
Корень проблемы на мой взгляд - то, что в ИТ многие пришли из других специальностей, не изучая Computer Science - базовые алгоритмы, устройство процессора, памяти, сетей, файловой системы. Либо из такого ВУЗа, который преподает по "советским" лекалам - т.е. устаревшую информацию.
Потому что если ты эти знания не получил в ВУЗе, то нужно желание учиться и годы опыта. Я, если что, пошел по второму пути)
А если нет ни базового образования, ни желания разбираться - получается узкий специалист, который "сломается" на первой же более менее сложной проблеме. А проблемы кто-то должен решать... и за это платят деньги)
P.S. 943 коммента показывают актуальность темы)
#computer_science #найм #devops
Нашел хорошую статью-боль https://habr.com/ru/articles/739452/
Она как бы про DevOps, но на самом деле нет - точно такая же проблема есть у разработчиков, тестировщиков, сопровождения.
Корень проблемы на мой взгляд - то, что в ИТ многие пришли из других специальностей, не изучая Computer Science - базовые алгоритмы, устройство процессора, памяти, сетей, файловой системы. Либо из такого ВУЗа, который преподает по "советским" лекалам - т.е. устаревшую информацию.
Потому что если ты эти знания не получил в ВУЗе, то нужно желание учиться и годы опыта. Я, если что, пошел по второму пути)
А если нет ни базового образования, ни желания разбираться - получается узкий специалист, который "сломается" на первой же более менее сложной проблеме. А проблемы кто-то должен решать... и за это платят деньги)
P.S. 943 коммента показывают актуальность темы)
#computer_science #найм #devops
Хабр
Я — айтишник, я не хочу много знать
За последнее время мне довелось провести немало технических собеседований на позицию DevOps инженера, в связи с чем появилась идея формализовать полученные выводы в этой статье. Хочу поделиться своими...
Всем привет!
Я уже рассказывал про один из вариантов ускорения запуска JVM приложений - использование native image https://t.me/javaKotlinDevOps/242
Напомню, основная идея была в том, что на этапе компиляции мы превращаем байт-код в нативный код. Можно рассматривать этот процесс как некий дамп универсального кода в конкретный, предназначенный для определенной процессорной архитектуры.
Похожий принцип используется и в случае JVM checkpoint/restore https://openjdk.org/projects/crac/ - проект CRaC.
Проект использует функционал Linux checkpoint/restore для Docker образов https://criu.org/Main_Page.
Т.е. в данном случае мы дампим все содержимое памяти JVM приложения на диск.
Работает, соответственно только для Docker и только в Linux, но кажется это не критическое ограничение.
Вот как это можно сделать на чистом Java приложении https://habr.com/ru/articles/719522/
Есть поддержка на всех основных платформах - Spring Boot, Micronaut, Quarqus, см. https://github.com/CRaC/docs
Проблему долгого первого запуска можно обойти либо сделав дамп до выхода на ПРОМ на идентичном Linux-е, либо разворачивая новые версии как канарейку или в моменты минимальной нагрузки, т.е. когда долгий старт не критичен.
Плюсом этого решения перед native image является то, что нет никаких ограничений на динамическую загрузки библиотек и рефлексию.
Кажется, одним из выгодоприобитетелей будут облачные провайдеры FaaS - Function as a Service, а если быть точным - их пользователи. И, собственно, так и есть - Amazon Lambda уже https://github.com/CRaC/aws-lambda-java-libs подддерживает
#crac #startup_time #jvm #performance #java_start_boost
Я уже рассказывал про один из вариантов ускорения запуска JVM приложений - использование native image https://t.me/javaKotlinDevOps/242
Напомню, основная идея была в том, что на этапе компиляции мы превращаем байт-код в нативный код. Можно рассматривать этот процесс как некий дамп универсального кода в конкретный, предназначенный для определенной процессорной архитектуры.
Похожий принцип используется и в случае JVM checkpoint/restore https://openjdk.org/projects/crac/ - проект CRaC.
Проект использует функционал Linux checkpoint/restore для Docker образов https://criu.org/Main_Page.
Т.е. в данном случае мы дампим все содержимое памяти JVM приложения на диск.
Работает, соответственно только для Docker и только в Linux, но кажется это не критическое ограничение.
Вот как это можно сделать на чистом Java приложении https://habr.com/ru/articles/719522/
Есть поддержка на всех основных платформах - Spring Boot, Micronaut, Quarqus, см. https://github.com/CRaC/docs
Проблему долгого первого запуска можно обойти либо сделав дамп до выхода на ПРОМ на идентичном Linux-е, либо разворачивая новые версии как канарейку или в моменты минимальной нагрузки, т.е. когда долгий старт не критичен.
Плюсом этого решения перед native image является то, что нет никаких ограничений на динамическую загрузки библиотек и рефлексию.
Кажется, одним из выгодоприобитетелей будут облачные провайдеры FaaS - Function as a Service, а если быть точным - их пользователи. И, собственно, так и есть - Amazon Lambda уже https://github.com/CRaC/aws-lambda-java-libs подддерживает
#crac #startup_time #jvm #performance #java_start_boost
Telegram
(java || kotlin) && devOps
Всем привет!
Сегодня расскажу про технологию native image.
Стандартная схема работы JVM приложения такая:
1) компилятор превращает исходники в байт-код
2) байт-код запускается на JVM
3) в процессе работы JVM анализирует использование байт-кода и при необходимости…
Сегодня расскажу про технологию native image.
Стандартная схема работы JVM приложения такая:
1) компилятор превращает исходники в байт-код
2) байт-код запускается на JVM
3) в процессе работы JVM анализирует использование байт-кода и при необходимости…
Всем привет!
Не ошибусь, если предположу, что многие Java разработчики знают об Sun code style conventions https://www.oracle.com/java/technologies/javase/codeconventions-contents.html
Их автоматическая проверка реализована в Checkstyle https://checkstyle.org/styleguides/sun-code-conventions-19990420/CodeConvTOC.doc.html
Но это еще не все, что предлагают себе и нам разработчики Java.
Во-первых Sun уже давно нет, есть Oracle, который его купил.
И есть более новая версия code style от Oracle https://cr.openjdk.org/~alundblad/styleguide/index-v6.html#toc-introduction (доступ по VPN)
А кроме того, у Oracle есть свои правила для проверки качества кода https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88487665
Ссылка выше ведет на раздел по обработке исключений, чтобы можно было оценить объем и глубину требований на конкретной фиче языка.
Что интересно - не все правила есть в SonarQube, по тем же исключениям увидел несколько новых для себя вещей.
Некоторые из них я полностью поддерживаю, они вроде как логичны и можно сказать очевидны https://wiki.sei.cmu.edu/confluence/display/java/ERR03-J.+Restore+prior+object+state+on+method+failure
Некоторые https://wiki.sei.cmu.edu/confluence/display/java/ERR06-J.+Do+not+throw+undeclared+checked+exceptions можно кратко суммировать так: да, я нашем языке есть дыры, но не надо их использовать, пожалуйста)))
Что хорошо - в конце страницы с описанием правила есть секция со ссылками на соответствующие правила SonarQube и прочих утилит статического анализа кода.
#java #code_static_analysis
Не ошибусь, если предположу, что многие Java разработчики знают об Sun code style conventions https://www.oracle.com/java/technologies/javase/codeconventions-contents.html
Их автоматическая проверка реализована в Checkstyle https://checkstyle.org/styleguides/sun-code-conventions-19990420/CodeConvTOC.doc.html
Но это еще не все, что предлагают себе и нам разработчики Java.
Во-первых Sun уже давно нет, есть Oracle, который его купил.
И есть более новая версия code style от Oracle https://cr.openjdk.org/~alundblad/styleguide/index-v6.html#toc-introduction (доступ по VPN)
А кроме того, у Oracle есть свои правила для проверки качества кода https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88487665
Ссылка выше ведет на раздел по обработке исключений, чтобы можно было оценить объем и глубину требований на конкретной фиче языка.
Что интересно - не все правила есть в SonarQube, по тем же исключениям увидел несколько новых для себя вещей.
Некоторые из них я полностью поддерживаю, они вроде как логичны и можно сказать очевидны https://wiki.sei.cmu.edu/confluence/display/java/ERR03-J.+Restore+prior+object+state+on+method+failure
Некоторые https://wiki.sei.cmu.edu/confluence/display/java/ERR06-J.+Do+not+throw+undeclared+checked+exceptions можно кратко суммировать так: да, я нашем языке есть дыры, но не надо их использовать, пожалуйста)))
Что хорошо - в конце страницы с описанием правила есть секция со ссылками на соответствующие правила SonarQube и прочих утилит статического анализа кода.
#java #code_static_analysis
Всем привет!
Я уже рассказывал про 5 возможных моделей ветвления в git https://t.me/javaKotlinDevOps/95
Нашел еще одну, причем уверен некоторым читателям этого блога она покажется знакомым)
Встречайте stacked pull requests.
Вот краткое описание https://www.michaelagreiler.com/stacked-pull-requests
А вот еще более краткое от меня:
1) работаем через Pull Requests (PR), они же Merge Requests
2) PR выстраиваем в лесенку
3) вливаем в обратном порядке
4) при изменениях в родительском PR, например, по результату код-ревью, проталкиваем изменения во все дочерние PR
Основное назначение данной схемы:
1) упор на ревью небольших кусочков кода, разделение фичи на мелкие commit-ы, удобные для ревью
2) разного рода миграции, когда на промежуточных стадиях код не компилируется и тесты не проходят, а все вместе - неудобоваримо для код ревью
Данная модель может работать поверх любого их описанных выше flow, за исключение trunk based. trunk based, напомню, вообще убирает Pull Requests, а процесс ревью осуществляется либо при парном программировании, либо пост-фактум.
Альтернативой является один PR с предположим 10 commits. Но преимущество данной схемы в том, что создавая вместо этого 10 PR автор скорее задумается о том, чтобы каждый из них представлял атомарное изменение, удобное для ревью.
#git #vcs #branching
Я уже рассказывал про 5 возможных моделей ветвления в git https://t.me/javaKotlinDevOps/95
Нашел еще одну, причем уверен некоторым читателям этого блога она покажется знакомым)
Встречайте stacked pull requests.
Вот краткое описание https://www.michaelagreiler.com/stacked-pull-requests
А вот еще более краткое от меня:
1) работаем через Pull Requests (PR), они же Merge Requests
2) PR выстраиваем в лесенку
3) вливаем в обратном порядке
4) при изменениях в родительском PR, например, по результату код-ревью, проталкиваем изменения во все дочерние PR
Основное назначение данной схемы:
1) упор на ревью небольших кусочков кода, разделение фичи на мелкие commit-ы, удобные для ревью
2) разного рода миграции, когда на промежуточных стадиях код не компилируется и тесты не проходят, а все вместе - неудобоваримо для код ревью
Данная модель может работать поверх любого их описанных выше flow, за исключение trunk based. trunk based, напомню, вообще убирает Pull Requests, а процесс ревью осуществляется либо при парном программировании, либо пост-фактум.
Альтернативой является один PR с предположим 10 commits. Но преимущество данной схемы в том, что создавая вместо этого 10 PR автор скорее задумается о том, чтобы каждый из них представлял атомарное изменение, удобное для ревью.
#git #vcs #branching
Telegram
(java || kotlin) && devOps
Всем привет!
Давно хотел написать про основные модели ветвления при работе c исходным кодом.
Итак поехали!
1) великий и ужасный gitflow.
Картинка: https://habrastorage.org/r/w1560/webt/ah/aw/yf/ahawyfcuk_rids2mljkuocattzg.jpeg
Описание: https://github.…
Давно хотел написать про основные модели ветвления при работе c исходным кодом.
Итак поехали!
1) великий и ужасный gitflow.
Картинка: https://habrastorage.org/r/w1560/webt/ah/aw/yf/ahawyfcuk_rids2mljkuocattzg.jpeg
Описание: https://github.…
Всем привет!
Минутка истории. И разных подходов к работе с opensource.
1-я история. Жила была компания Microsoft, и в какой-то момент она "запустила" свою инфраструктуру разработки. Были выделены ресурсы для исправление этой ситуации. Один из примеров такой деятельность - перенос исходников в git, создание своего форка git, проверка его на GitHub и вливание форка в основную ветку git. Вот тут немного подробнее про доработку git под требования Microsoft - большой объем репозитория - https://habr.com/ru/articles/795635/
2-я история. Жила была компания Facebook, тогда еще не иноагент) Компания была молодая, но тоже уже столкнулась с проблемой хранения и организации код-ревью на большом объеме кода. Разработчики компании готовы innersource-ить, чтобы решить проблему. Постучались в git, получили отказ с формулировкой - это частный случай, для основной массы пользователей не нужно, делайте маленькие репозитории. Постучались в Mercurial - там ее pull request согласились принять. Перешли на Mercurial https://habr.com/ru/articles/798881 Но предположу, что часть разработчиков на этом не успокоилась и в результате появился Sapling https://sapling-scm.com/docs/introduction/differences-hg
Это новая Version Control System, которая может работать как со своим форматом repo, так и с git. При этом делает упор на частичное клонирование репо и работу с коммитами: быстрый откат, сохранение истории изменений при слиянии коммитов и даже https://sapling-scm.com/docs/commands/absorb
Тут наверное нужна мораль...)
На первый взгляд подход git более последователен - выбрали лидера рынка, допилили, вернули в основную ветку, помогли opensource сообществу. Но с другой стороны git хоть и является стандартом, но не идеален. И Sapling решает ряд его проблем. Кто-то должен протаптывать новые тропы, пусть и ценой чуть большего беспорядка в своей инфраструктуре разработки
#git #vcs
Минутка истории. И разных подходов к работе с opensource.
1-я история. Жила была компания Microsoft, и в какой-то момент она "запустила" свою инфраструктуру разработки. Были выделены ресурсы для исправление этой ситуации. Один из примеров такой деятельность - перенос исходников в git, создание своего форка git, проверка его на GitHub и вливание форка в основную ветку git. Вот тут немного подробнее про доработку git под требования Microsoft - большой объем репозитория - https://habr.com/ru/articles/795635/
2-я история. Жила была компания Facebook, тогда еще не иноагент) Компания была молодая, но тоже уже столкнулась с проблемой хранения и организации код-ревью на большом объеме кода. Разработчики компании готовы innersource-ить, чтобы решить проблему. Постучались в git, получили отказ с формулировкой - это частный случай, для основной массы пользователей не нужно, делайте маленькие репозитории. Постучались в Mercurial - там ее pull request согласились принять. Перешли на Mercurial https://habr.com/ru/articles/798881 Но предположу, что часть разработчиков на этом не успокоилась и в результате появился Sapling https://sapling-scm.com/docs/introduction/differences-hg
Это новая Version Control System, которая может работать как со своим форматом repo, так и с git. При этом делает упор на частичное клонирование репо и работу с коммитами: быстрый откат, сохранение истории изменений при слиянии коммитов и даже https://sapling-scm.com/docs/commands/absorb
Тут наверное нужна мораль...)
На первый взгляд подход git более последователен - выбрали лидера рынка, допилили, вернули в основную ветку, помогли opensource сообществу. Но с другой стороны git хоть и является стандартом, но не идеален. И Sapling решает ряд его проблем. Кто-то должен протаптывать новые тропы, пусть и ценой чуть большего беспорядка в своей инфраструктуре разработки
#git #vcs
Хабр
Итак, вы думаете, что знаете Git? Часть третья: реально большие репозитории
Автор оригинала Скотт Чакон — сооснователь GitHub и основатель нового клиента GitButler. Этот клиент ставит во главу угла рабочий процесс и удобство разработки, в том числе код-ревью, и не является...