От legacy-зависимости к своему composer-пакету

Иногда идея для отдельного open source пакета появляется не из желания придумать что-нибудь новое, а ровно наоборот: начинаешь разбирать старый проект и находишь там решение, которое когда-то было нормальным, а теперь уже мешает двигаться дальше.
Так получилось с моим старым symfony-shop
Во время модернизации проекта я добрался до авторизации через Яндекс. Она была реализована через пакет rakeev/oauth2-yandex. Сам по себе подход был вполне обычным: вместо того чтобы самостоятельно реализовывать весь OAuth 2.0 flow, приложение использовало готовый провайдер.
Проблема была в возрасте зависимости
Последние изменения в rakeev/oauth2-yandex относятся ещё к 2017 году. За это время PHP, библиотеки вокруг него и инструменты разработки заметно изменились. При тестировании обновлённого приложения старая зависимость уже начала напоминать о себе предупреждениями и долго, когда deprecated перейдет в error
И здесь было несколько вариантовСамый быстрый: убрать пакет и написать необходимый код прямо внутри symfony-shop. Для одного проекта это вполне рабочее решение. Несколько классов, немного настройки, авторизация снова работает — задача закрыта.
Но у такого подхода есть очевидный минус: решение остаётся внутри конкретного приложения.
Если завтра авторизация через Яндекс понадобится в другом проекте, всё начинается заново.
Можно было пойти в другую сторону и попытаться оживить старый пакет. Но мне хотелось получить небольшое современное решение с понятной зоной ответственности и без необходимости тащить за собой архитектурные решения проекта восьмилетней давности.
Поэтому появился третий вариант — сделать отдельный пакет.
Так начался yaleksandr89/oauth2-yandex
Вместо реализации OAuth-механики с нуля пакет построен поверх league/oauth2-client.
Это важный момент
Задачей было не написать «свой OAuth 2.0», а реализовать именно особенности Yandex ID: нужные endpoints, получение токена, обновление токена, загрузку профиля пользователя и преобразование ответа Яндекса в удобные PHP-объекты.
Общие части OAuth при этом остаются в библиотеке, которая специально для этого и существует.
В результате получилось довольно простое разделение ответственности:
- league/oauth2-client отвечает за общую механику OAuth 2.0;
- oauth2-yandex знает, как работать конкретно с Yandex ID;
- само приложение занимается уже своей бизнес-логикой.
Для Symfony отдельный велосипед тоже не понадобился. Пакет можно использовать через KnpUOAuth2ClientBundle, как универсальный OAuth провайдер.
То есть oauth2-yandex при этом не становится Symfony-пакетом и не привязывается к одному framework.

Но написать рабочий класс — это была только часть задачи.
Если уж выносить решение в open source, хотелось довести его хотя бы до состояния, когда его действительно можно подключить в чужой проект, а не только показать в GitHub со словами «у меня работает». Поэтому постепенно появились:
- тесты
- статический анализ
- проверка code style
- CI
- Codecov
- документация
- пример интеграции с Symfony
- описание публичного API
- документация
- GitHub Release
- публикация на Packagist
После релиза пакет дополнительно проверялся через чистую установку Composer в отдельном проекте.
В итоге история получилась забавная
Начиналось всё буквально с задачи: «убрать устаревшую зависимость из старого Symfony-проекта».
А закончилось отдельным composer-пакетом, который больше никак не зависит от symfony-shop и может использоваться в других приложениях.
И, пожалуй, именно такой open source мне нравится больше всего.
Не пытаться придумать очередной «революционное решение», а найти небольшую реальную проблему, отделить её от конкретного проекта и сделать решение, которым при необходимости сможет воспользоваться кто-то ещё.
Ссылки:
- GitHub
- Packagist
- Старый пакет, с которого началась эта история
#разбор #backend #процессы