К основному контенту

Заметки по версионированию API

Я недавно посмотрел курс Designing & Versioning HTTP/REST APIs от Jeffrey Richter, известнейшего автора таких основополагающих книг как CLR via C# и Windows API via C++. Надеюсь, вы сталкивались с ними или даже читали их.

Я рекомендую этот курс к просмотру, особенно тем, кто считает что дизайн API это легко (что-то вроде "перекладывания JSON'ов"). Однако, как и с многими другими курсами, просмотр такого материала не даёт нужного глубокого понимания вопросов. Даже с таким автором.

Комбинирование практики с теорией обязательно в основоении любого материала, а тем более в применении его в условиях релиза

Эта рекомендация относится к разработчикам любого уровня. Легко просмотреть курс и поставить новую галочку в резюме, однако "Дьявол кроется в деталях". Во время реальной разработки возникает множество вопросов, о которых не так просто вспомнить в момент обучения.

Ну, довольно слов. Давайте рассмотрим конкретный пример, часть курса по теме Versioning HTTP APIs и заглянем в уголки, которые были не покрыты автором, хотя являются необходимостью во время применения его советов.

REST API повсюду

Большинство API работают по протоколу REST. Остальные протоколы, вроде gRPC, SOAP, GraphQL и другие, созданы для решения задач специфичных компаниям и продуктам, тогда как REST покрывает наиболее широкий спектр проблем и вариантов использования. Например:

  • Он доступен для любого типа клиента: старые и новые компьютеры, старые и новые браузеры, смартфоны, планшеты, IOT устройства (Raspberry Pi и прочие), и даже консоли.
  • Испрользуется HTTP протокол, доступный на любом языке и из любого утюга, и предоставляющий из коробки достаточно функционоала для обеспечения API, такого как: коды ошибок, проброс информации об аутентификации (токены, ключи, коды, и проч.), передача любого типа контента, контроль ширины полосы и проч.
  • Огромное количество примеров кода для новичков.
  • и т.д.

Честно говоря, для прототипов, небольших местечковых решений и быстрой разработки этого достаточно с головой. Все остальные протоколы решают свои задачи, такие как работа на Enterprise рынке продуктов (крупных компаний), доступность при неустойчивой связи, масштабируемость до миллиардов пользователей, и т.д. 

Эта простота одновременно играет и злую шутку. Многие не задумываются о переходе от Private к Public API и не знают о том насколько значим этот переход на самом деле. Далеко не каждый разработчик в курсе что API должно быть оброатно совместимо с предыдущими версиями, а иногда и совместимо с будущими версиями. Малая часть разработчиков представляют как это реализовать.

Что не так с публичным API?

Версионирование API играет важную роль в том чтобы сделать ваших клиентов счастливыми. Как только вы опубликовали свою первую Альфа-версию API публично, всё становится для вас сильно сложнее, чем было прежде.

Вам придётся поддерживать всю базу клиентов начиная с версии 1.0-pre-alpha и заканчивая вашей самой последней версией 99999...9.0... если конечно вы не догадались выпустить документ с Политикой использования вашего публичного API

В таком документе вы можете рекомендовать вашим клиентам обновляться на каждую версию вашего API, делая предыдущую более неактуальной. Однако помните, что это лишь ваша рекомендация. Очень врядли клиенты ей последуют (причем, дело не только в лени, но часто в невозможности).

Вы можете отказаться от всех гарантий поддержки работоспособности предыдущих версий. Однако, это зависит от ваших отношений с клиентами, и иногда это просто невозможно.

В любом случае, не стоит недооценивать такую вещь как Версия API. Она (должна) помогает вашим клиентам понять чего ожидать от API и как его использовать.

Просто следуй совету автора. Что может пойти не так?

По сути, версия API это такая отметка, обычно в буквенно-цифровом виде, но не обязательно. Чаще всего применяются либо номера, либо даты. А также, версия может быть указана немного по разному. Рассмотрим примеры:

Как можно видеть, есть разные способы рассказать клиенту о версии. И прежде чем просто выбрать понравившийся, надо взвесить потенциальные причины использования того или иного способа. Может показаться, что эти варианты "на ваш вкус", однако не всё так просто.

Фундаментально, всего два основных способа предоставить версию API:

  1. Как Path часть URL
  2. Как Parameter часть URL

В различных источниках упоминается что путь №1 уже устаревший. Однако, на самом деле, всё ещё есть ряд причин использовать и его.

Когда стоит требовать версию в пути:

  • Большинство систем управления API (API Management systems) используют этот путь как путь по умолчанию. Я говорю о продуктах Axway, MuleSoft Anypoint, Google Apigee, Boomi, AWS API portal, Nginx API Management. В них есть возможность настроить и №2, однако то, как это сделано, выглядит довольно костыльно и может плохо работать, что добавляет рисков.
  • Сервисы, которые выставлены за одним и тем же DNS, должны использовать один способ версионирования. Поэтому, если у вас уже какой-то API версионируется этим способом, то боюсь, придется продолжать следовать этому пути. Ну, либо решать инфраструктурные вопросы.

Когда стоит требовать версию в параметре:

  • Гарантирует стабильность пути, даже для будущих версий API. Ведь меняется только параметр, а не путь.
  • Можно отдавать поведение "по-умолчанию" когда версия не указана совсем.
  • Даёт больше прозрачности клиентам, т.к. в версии можно сказать больше информации, такой как дата, и степень готовности: -preview, -beta, -release
  • Можно легко переключать версии с -preview или -beta на -release, делая разработку более итеративной.
  • Можно отделить версию поведения API от версии Ресурса (если помните, REST, это про Resource Transfer).
  • Поддержка функционала Группирования версий, которая позволяет разработчикам использовать один номер версии на несколько различных точек доступа.

Забавно, что такие детали не покрыты в курсе, хотя являются важной частью разработки. Именно поэтому нужно  комбинировать теорию с практикой.

Ещё несколько моментов

Подход к версионированию API нельзя менять на ходу, он должен быть продуман заранее. Каждый раз когда вы хотите изменить обязательный параметр метода, или формат данных, сменить коды ошибок или поведение, вам нужно будет создавать новое API (новые методы, новые контракты, с новыми форматами и параметрами) и новую версию.

Будет даже лучше, если структуры данных будут также версионироваться. Вам это может быть не нужно на первых этапах, но вы будете благодарить себя за это при необходимости масштабировать ваше решение или перейти на Event-Driven архитектуру.

Выводы

Следовать этим правилам сделает ваших клиентов счастливее, а вашу жизнь чуть легче (хотя не сильно).

Как вы могли заметить, в целом, многое отдается на ваше усмотрение, начиная от политик использования API и до технических деталей реализации. Но всё это, к сожалению, часто не покрывается в курсах и книгах и вам придется решать это самостоятельно.

Поэтому практика всегда должна чередоваться с теорией. 

Ссылки

Microsoft API guidelines
ASP.NET versioning examples

 

Комментарии

Популярные сообщения из этого блога

Делаем себе бесплатный VPN на Amazon EC2

Читать этот пост в Telegraph. Другие посты в канале в Telegram. Кто только не расписывал уже пошаговые инструкции по этой теме. Однако, время идёт, ПО меняется, инструкции нуждаются в обновлении, а люди в современной России всё больше нуждаются в применении VPN. Я собираюсь описать все шаги для создания бесплатного сервера на Amazon EC2 с операционной системой Linux и необходимые команды для настройки VPN сервера на нём. Чтобы не повторяться о деталях, которые были много раз описаны на русскоязычных и англоязычных ресурсах, по ходу статьи я просто приведу целую кипу ссылок, где можно почерпнуть необходимую информацию, а где информация устарела - опишу подробнее что нужно сдеать. В итоге, сервер будет доступен для вас из любой точки планеты, с любой операционной системы, и бесплатно (с определёнными ограничениями по трафику). Шаг первый - Регистрируемся на Amazon AWS Нужно зайти на сайт https://aws.amazon.com/ru и сразу перейти к Регистрации, нажав одноимённую кнопку. При р

В помощь программисту: инструкции по работе с Ubuntu сервером

Программистам чаще приходится писать код и заботиться о его чистоте, правильных абстракциях в коде, корректных зависимостях и прочих сложностях профессии. При этом, настройка и обслуживание серверов, хоть и связанная область - это отдельный навык, необходимый не каждому, и помнить о котором в деталях сложно. Поэтому, я делаю ряд микро-инструкций, которыми буду пользоваться и сам, когда необходимо. Это не статьи, а пошаговые помощники, которые я буду дополнять и наполнять по мере надобности. Делаем бесплатный VPN на Amazon EC2 Создание ключей SSH Подключение к серверу через SSH Передача файла с Linux сервера наWindows машину Делаем VPN сервер на Ubuntu 20.04 используя OpenVPN и EasyRSA  Отображение GUI с Linux сервера на Windows машине

Выбираем все плюсы из трех парадигм Entity Framework

Между парадигмами разработки с Entity Framework (Code First, Model First, Database First) я выбрал промежуточную, потому что ни одна меня не устраивала полностью. В Code First меня радуют чистые POCO классы, но не устраивает невозможность моделирования базы. В Database First и Model First мне не нравится генерация EDMX и другого всего лишнего. Таким образом, я нашел для себя такое решение: 1. Я моделирую схему в любой удобной программе (тут любая внешняя программа моделирования, генерирующая SQL Server-совместимые скрипты генерации базы) Рис. Смоделированная схема БД. 2. Создаю базу в SQL Management Studio 3. Делаю Reverse Engineering базы в POCO классы (как в Code First) с помощью плагина Entity Framework Power Tools Рис. Установленный плагин для Reverse Engineer. Рис. Вот так делается Reverse Engineer базы данных в POCO классы. Рис. Результат генерации POCO классов на основе базы данных: папочка Models с готовым контекстом, классами объектов и маппинг-классами.