Елизавета Акманова
Старший аналитик ГК Юзтех
Всех приветствую в своей новой статье! Меня зовут Елизавета Акманова. С некоторыми читателями уже знакомы с предыдущих тем, для новых представлюсь: я системный/бизнес аналитик с опытом работы 3 года. Было много проектов разного уровня и сложности: начиная с монолитов в команде из 4 человек, заканчивая 50+ микросервисами из 90 человек. Но все проекты объединяло одно: API. Абсолютно в каждом присутствовал этот термин, приходилось работать с проектированием API, и сегодня я хотела бы рассказать про подходы, как это можно делать и подчеркнуть особенно метод API-first.
Предпосылки
Зачем вообще нужны все эти технологии? В 2011 году ООН признала интернет базовым правом человека, а сегодня некоторые товары, такие как кроссовки, оснащены мобильными приложениями, взаимодействующими с удаленными серверами. В связи с ростом сложности требуется эффективное управление. Спойлер: в этом может помочь API-first. Но прежде чем перейти к этому, давайте рассмотрим, как менялась роль API в нашей повседневной жизни.
Все началось с клиент-серверного взаимодействия. Эта концепция появилась задолго до моего рождения. В 1992 году был представлен самый ранний протокол HTTP 0.9, что стало катализатором развития веб-приложений. К началу 2000-х годов была опубликована диссертация о распределенных архитектурах, в которой впервые упомянут термин REST. Это можно считать началом культурного развития API.
В то время архитектура наших приложений выглядела следующим образом:
Это простой монолит, включающий в себя и фронтенд, и бэкенд, а пользователь взаимодействует непосредственно с ним. Если необходимо предоставить доступ сторонним приложениям-интеграторам, они интегрируются непосредственно с этим монолитом.
Такое решение сталкивается с несколькими проблемами: фронтенд может быть достаточно тяжелым, да и масштабировать монолит это то еще удовольствие. Возникает осознание ценности API, хотя поначалу он чаще всего рассматривается как средство для интеграции.
С момента появления смартфонов, в 2000 году, приходит понимание, что нам нужны API-центричные приложения. Из названия следует, что у нас ядром системы является API. Архитектура начинает выглядеть как-то так: в центре наш API, а клиенты (веб, мобилка, десктоп) становятся достаточно легкими и дешевыми в разработке, так как это небольшая прослойка поверх API.
Если нам нужно предоставить доступ интеграторам, они это делают также через API.
Code-first
Когда разработчику нужно быстро развернуть API, переход непосредственно к написанию кода после получения бизнес-требований ускорит развертывание API. Иногда это самый быстрый вариант.
Но у этого есть минусы. Во-первых, если посмотрим с точки зрения процессов и результатов, то такой подход приводит к тому, что иногда мы получаем при разработке API не то, что нам нужно. Дальше в статье будет наглядный пример того, какие проблемы могут появиться при некачественном проектировании API.
Во-вторых, многие проблемы могут появиться на этапе интеграции. После того как мы создали что-то, предоставили возможность попробовать, мы осознали, что упустили некоторые аспекты, у нас возникли неэффективные сценарии, и, банально говоря, API оказалось неудобным.
В-третьих, API часто становится узким местом. Пока разрабатывается API, зависимые команды (тестировщики, мобильные разработчики, фронтендеры) вынуждены ждать. Они не могут начать свою работу до завершения процесса разработки API, и процесс выглядит примерно так:
Сначала пишется код, деплоится, создаются функциональные тесты и документация, после чего мы передаем зависимым командам, чтобы они могли начать разрабатывать клиентскую часть. Однако этот процесс занимает много времени и часто становится узким горлышком. Как я отмечала ранее, многие проблемы становятся явными только на этапе интеграции, что происходит довольно часто. Исправление таких ошибок обходится дорого, и в итоге мы вынуждены перезапускать весь цикл разработки заново. Как аналитик, который работал, в том числе с готовыми API, я могу сказать вам, что задача исправления плохо написанных API — это кошмар.
Одно лишь слово — дорого.
API-first
Что мы можем с этим сделать? Мы можем начать не с разработки API, а с проектирования. Первым шагом будет создание детального описания контракта.
API First — процесс разработки API, который фокусируется именно на аспекте проектирования при создании API. При данном подходе проектировщики создают подробную спецификацию API до начала кодирования. Эта спецификация служит образцом для разработчиков, чтобы гарантировать, что API построен в соответствии с желаемыми функциональностью и требованиями.
Этот подход может привести к следующим результатам:
Способствует повышению качества. Почему? Описание контракта стоит значительно дешевле, чем написание кода. Это можно легко сделать в текстовом редакторе, даже в блокноте, а затем передать на ревью. Процесс выглядит следующим образом:
Мы создали контракт, пригласили опытных разработчиков на ревью, получили от них обратную связь, выявили недочеты и легко внесли правки, ведь это всего лишь текст. Мы продолжили этот цикл, пока не достигли согласования.
Мы снижаем стоимость ошибок. В процессе ревью мы можем пригласить не только опытных бекенд-разработчиков и проектировщиков, но и наших интеграторов, коллег из зависимых команд. Они также могут предоставить обратную связь, указать на недочеты или неудобства.
Мы утвердили контракт, и теперь у нас достаточно информации для начала параллельной разработки. Контракт становится первичным источником правды. Мы распространяем его среди команд: бекенд-разработчики начинают создавать API, тестировщики разрабатывают функциональные тесты, а фронтендеры, мобильные разработчики и другие команды начинают работу над своими решениями, опираясь на контракт и создавая моки API.
Несмотря на это зависимость все равно остается, потому что интеграторы не могут выпустить свое решение, пока нет готового API, но при этом мы выигрываем в скорости.
Также у нас улучшается и сам процесс разработки. Без продуманного API процесс разработки может стать хаотичным, неуклюжим и разрозненным. В ходе такой работы можно допустить много ошибок при написании кода. API-first удобен для разработчиков, позволяя им быть вовлеченными и сосредоточенными на конечном результате, не отвлекаясь и не задерживаясь из-за плохо написанных и несогласованных API. В конечном счете, счастливые разработчики = счастливое API.
Примеры из жизни, когда что-то пошло не так
Один из наиболее запоминающихся и впечатляющих кейсов был связан с ошибкой в маппинге при интеграции со смежным сервисом. Инцидент заключался в том, что необходимо было выставлять статус, где 1 - like, 2 - dislike. По итогам маппинг с другими системами работал с точностью, да наоборот. И за последние 3 месяца сотрудники получали инвертированные оценки при работе с клиентами. И на основе этих данных принимались разные HR-решения. Итог: самых эффективных, продуктивных и качественных сотрудников уволили, а их антиподам выдали бонусы.
Этот инцидент выявил проблемы в двух командах одновременно:
Проблемы смежной системы:
Разработка, вероятно, предполагала, что их API предназначено для внутреннего использования. Однако в ходе развития предприятия API стали использовать и смежные сервисы. Отсутствие заботы о внешнем пользователе стало причиной того, что даже технический специалист не справился с тривиальной задачей, связанной с лайками и дизлайками.
Отсутствие документации и проекта API также могло привести к тому, что описание маппинга не было доступно.
Проблемы текущей системы:
Допустим, документация и проект API были. Но, видимо, текущая команда решила пустить разработку вперед и получилось то, что получилось.
При подходе API-first во время привлечения всех заинтересованных сторон и совместной работы кто-то наверняка мог бы указать на проблему в маппинге, ну или как минимум подсветить возможность ее наличия.
Относительно недавно наткнулась на очень интересную статистику. Лично у меня вызывает тревогу тот факт, что только 10% организаций полностью документируют свои API, согласно отчету Enterprise Management Associates (EMA) за 2023 год. Это говорит нам о том, что мы не заботимся о потребителях API, о конечных пользователях. Разрабатывая без документации, мы оставляем пользователей в неведении и лишаем их возможности полноценно использовать наши ресурсы. Это приводит к увеличению затрат на поддержку и обслуживание, создает преграды для внешних разработчиков и так далее, проблемы можно перечислять вечно.
С чего начать?
И напоследок я хотела бы успеть дать советы, потому что я рассказала, что API нужен, API должен быть первым, должны быть контракты. Но нужно еще посоветовать с чего начать.
Первое, что я рекомендую: это пользоваться RAML для проектирования. Расшифровывается как restful API modeling language. Это yaml, в нем просто описывается контракт, он легко читается, понятный, его можно распространять.
Я советую внедрить процесс contract review, чтобы валидировать контракты. Это помогает развитию культуры проектирования API, это помогает развитию молодежи (junior) в команде разработки, это полезно. Когда мы общаемся/обсуждаем, мы неизбежно развиваемся.
Хранить артефакты. Во-первых, контракт должен быть сохранен, чтобы его можно было предоставить тому, кому он нужен. Можем хранить его прямо в гите, рядом с кодом. Во-вторых, интересно фиксировать изменения контракта со временем, чтобы отслеживать его изменение, почему это происходило. На этом тоже можно строить выводы, это можно давать молодым разработчикам чтобы они учились вот это также способствует развитию культуры проектирования API.
В заключении хочу отметить, что на одном из проектов разработчики стали инициаторами в использовании формата RAML для проектирования API. Этот подход оказался очень удобным для создания и согласования контрактов, а также для упрощения процессов разработки и тестирования. Впоследствии, на другом проекте, инициатива использовать RAML исходила уже от тестировщиков, занимающихся написанием автотестов, поскольку им было важно иметь понятное и четкое описание API для автоматизации тестирования. Эти два успешных внедрения убедили меня в преимуществах RAML, и теперь я почти всегда использую этот инструмент в своих проектах.
Плюс ко всему, RAML легко конвертируется в swagger. Swagger это уже стандарт спецификации, вокруг него есть большая экосистема. Они помогают автоматически генерировать тесты, генерировать клиентов, там можно потыкаться в API, дать кому-нибудь попробовать повзаимодействовать.
Использование RAML для описания контрактов, внедрение процесса contract review и хранение артефактов являются ключевыми аспектами, которые помогут вам создать надежные и поддерживаемые API. Эти практики способствуют развитию культуры проектирования API в команде, помогают младшим разработчикам учиться и расти, а также обеспечивают прозрачность и отслеживание изменений.