(java || kotlin) && devOps
357 subscribers
7 photos
1 video
7 files
354 links
Полезное про Java и Kotlin - фреймворки, паттерны, тесты, тонкости JVM. Немного архитектуры. И DevOps, куда без него
Download Telegram
Версионирование для REST в Java - оно как бы есть, и его как бы нет)

Основная проблема с версионированием - которую многие, в т.ч. и я, не замечают - следующая.
Версионирование нужно и его почти везде используют, но при этом Spring, который также везде используют, не делает ничего для его поддержки.
Точнее не делал.
Начиная со Spring 7, который уже вышел, данный функционал наконец таки появился: https://habr.com/ru/companies/spring_aio/articles/967454/

Что добавили:
1) определение способа передачи версии:

# Path segment versioning (e.g., /api/v1/users)
spring.mvc.apiversion.use.path-segment=1

# Request header versioning (e.g., X-API-Version: 1.0)
spring.mvc.apiversion.use.header=X-API-Version

# Query parameter versioning (e.g., ?version=1.0)
spring.mvc.apiversion.use.query-parameter=version

# Media type parameter versioning (e.g., Accept: application/json;version=1.0)
spring.mvc.apiversion.use.media-type-parameter[application/json]=version


2) указание версию по умолчанию:

# Basic versioning configuration
spring.mvc.apiversion.default=1.0


3) указание списка поддерживаемых версий и, соответственно, их валидацию:

spring.mvc.apiversion.supported=1.0,2.0


или

# автоматическое детектирование по содержимому контроллеров
spring.mvc.apiversion.detect-supported = true


Естественно, все это можно сделать через код.

4) Стандартный парсер версий - по стандарту семантического версионирования

5) Само собой есть возможность определить нестандартный механизм передачи и формата версий через создание ApiVersionResolver и ApiVersionParser

6) Есть даже ApiVersionDeprecationHandler - стандартизация уведомления клиента об устаревших версиях и автоматическая 400-ка для неподдерживаемых

7) И конечно механизм маршрутизации по версиям, который автоматически разрешает вот такую конструкцию:

public class AccountController {
@GetMapping
public Account getAccount() {
}

@GetMapping(version = "1.1")
public Account getAccount1_1() {
}

@GetMapping(version = "1.2+")
public Account getAccount1_2() {
}

@GetMapping(version = "1.5")
public Account getAccount1_5() {
}
}


8) аналогично для endpoint в функциональном стиле:

RouterFunction<ServerResponse> route = RouterFunctions.route()
.GET("/hello-world", version("1.2"),
request -> ServerResponse.ok().body("Hello World")).build();


9) плюс все поддерживается для reactive stack

10) и на клиенте (для тестовых клиентов тоже):

RestClient client = RestClient.builder()
.baseUrl("http://localhost:8080")
.apiVersionInserter(ApiVersionInserter.useHeader("API-Version"))
.build();
...
Account account = client.get().uri("/accounts/1")
.apiVersion(1.1)
.retrieve()
.body(Account.class);


Еще одна важная фича, которая должна была появиться раньше.

#spring #versioning
Зоопарк консолей в Windows.

Пишу на примере Windows 11, но в 10-ке начиная с определенного билда все также.

1) Стандартная консоль Windows - теперь их стало две:
а) это связано с тем, что в Windows появился т.наз Windows Terminal. Это мультиоконная консоль, и при вызове cmd.exe вызывается именно именно. Но т.к. она мультиоконная - там же можно открыть любую другую консоль. Все в IDEA слизали)
б) а старая добрая однооконная консоль вызывается через conhost.exe. Зачем может пригодится старая консоль? Microsoft любят ломать совместимость, и новая консоль к примеру изменила API в плане скрытия окна консоли при старте программы.

2) Powershell - тоже использует Windows Terminal, и их стало даже три:
a) powershell.exe - это старая добрая синяя консоль (цвет значка остался синий, консоль по умолчанию черная), версия 5.х
б) pwsh.exe - новая черная консоль (я снова про цвет значка), версия 7.x. На данный момент ставится только руками. Ключевое замеченное мной отличие - есть API по считыванию данных в консоли, что удобно при работе AI агента, не надо выводить данные в лог.
в) conhost.exe powershell.exe - это способ запустить powershell в старом однооконном режиме

3) Git Bash - очень удобная штука, получаем консоль Linux с большим количеством утилит. Увы, не полный набор, а главное не хватает pacman - менеджера пакетов, который в свою очередь даст поставить все остальное. Еще важная особенность - там используются linux слэши и набор переменных среды хотя и наследуется, но отличается от Windows.

4) если утилит не хватает - можно поставить MSYS. Git Bash = урезанная версия MSYS без pacman + mingw64 (С-шный комполятор gcc в Windows)

5) еще можно поставить WSL - Windows Subsystem for Linux. Поверх нее работает Docker Desktop, а это значит не можно, а нужно ставить). В этом случае появляется еще консоль wsl.exe

В итоге у меня это выглядит как на картинке.
Но в целом получаем рабочую среду)

#win #dev
🤯21
Отличие сеньора от джуна

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

Но не суть.
Понравилась одна фраза:
В реальных проектах всегда будет "говнокод", т.к. есть сроки. Ключевой момент в том, что сеньор всегда может аргументировано объяснить, почему он написал именно так, а джун - нет)

#memes #dev
👍3
Концепция venv (virtualenv) в Python

Концепция крутая, как по мне ноутбуки и виртуальные окружения - две самые крутые фичи в Python.

Если вкратце о ее сути: ты создаешь для каждого проекта отдельную виртуальную среду, со своим интерпретатором Python (разные версии) и своим набором библиотек.
Это удобно, и решает проблему конфликта зависимостей. Небольшое уточнение: если бы все сервисы и библиотеки явно указывали версии зависимостей - конфликтов бы не было, но мы же говорим о реальном мире.
К слову, концепцию позаимствовала и Java, я про jenv - https://t.me/javaKotlinDevOps/442 - правда, ограничить можно только версию Java.

Но блин.
Почему утилит, реализующих виртуальные окружения столько:
- venv
- virtualenv
- uv
- Poetry
- PDM
- Hatch
- Rye
- Conda
- Mamba
- Micromamba
- Pixi
- Pipenv
- pyenv-virtualenv
- virtualenvwrapper
- Tox
- Nox
- Devbox
- Flox
- Devenv.sh
- Spack
- Vex
????

Явная иллюстрация анекдота про 10 стандартов)

Ясно, что они не идентичны по функционалу.
1) кто-то добавляет возможность менеджера пакетов (и это правильно),
2) кто-то позволяет формировать список зависимостей проекта requirements.txt (и это тоже правильно),
3) кто-то добавляет возможность делать lock зависимостей (спорная фича IMHO).
Кто-то просто устарел. Кто-то заточен для тестов, где нужна куча разных сред. Кто-то просто добавляет небольшие фишки в другой менеджер, типа убирает необходимость явно включать использование виртуального окружения в консоли (activate).
Но все же...
Причем 4 из них имеют официальный статус)

P.S. Самой крутой и современной считается uv. На данный момент.

#python #java #virtual_env
Про практическое применение AI в разработке

"Низколежащий фрукт" - добавление в проект новых зависимостей.
В IDEA как бы есть для этого auto complete в build и pom файлах. Но работает он... плохо.

Maven. Я вбиваю любую часть имени groupId или artefactId зависимости - и IDE мне ее находит и подставляет всю конструкцию:
<dependency>
...
</dependency>
С плагинами тоже работает, правда есть один момент - у зависимостей и плагинов общий индекс, поэтому чтобы искать плагины нужно вначале вбить groupId. А у всех стандартных плагинов он одинаковый - org.apache.maven.plugins.

Вроде все работает? Нет. Заставить работать индекс по mavenCentral у меня не получилось. А что же работает? Поиск по зависимостям из локального репо. Но его вначале нужно наполнить. Причем эту проблему - поиск по удаленному репозиторию - я помню уже лет 5 минимум.

С Gradle все еще хуже. Тоже ищет только локальные зависимости, но работать нормально не возможно. Для добавления зависимости вначале нужно написать implementation, и начать набирать точное имя зависимости с начала. А плагины не ищет совсем.
Пробовал с Groovy и Kotlin DSL.

Так что тут AI спасет. Но в агентском режиме, не auto complete, т.к. для работы auto complete нужен электрод в мозг, а до этого техника еще не дошла. Т.е. нужен немного другой паттерн работы, но это в целом касается работы с AI.

#maven #gradle