Жизненный цикл разработки ПО (Software Development Life Cycle, SDLC) — это процесс управления программным обеспечением на протяжении всего времени его существования, от планирования до вывода из эксплуатации. API относится к программному обеспечению, поэтому термин «жизненный цикл API» синонимичен SDLC. Даже если ваш API не пройдет полный цикл, понимание того, из каких этапов тот состоит, поможет вам выработать подход к разработке.

Жизненный цикл API состоит из таких этапов, как: планирование, проектирование, реализация, тестирование, развертывание, сопровождение и выведение из эксплуатации. Все эти этапы показаны на рис. 1.7.

Хотя есть тенденция рассматривать этапы жизненного цикла API (или SDLC) как независимые, следующие друг за другом, в действительности они тесно взаимосвязаны. Например, на этапе реализации могут обнаружиться факторы, не учтенные при проектировании, что приведет к изменениям в исходном проекте. Кроме того, мы не указываем, какой этап проекта является начальным, поскольку это зависит от временны́х рамок вашего проекта.

Рис. 1.7. Жизненный цикл API
Рис. 1.7. Жизненный цикл API

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

Создание документации в некоторых проектах откладывается до этапа сопровождения. Считается, что нет смысла документировать программное обеспечение, разработка которого еще не завершена. Главный недостаток такого подхода заключается в том, что разработка ПО продолжается до момента вывода его из эксплуатации, и если ждать завершения, то документация не появится никогда. Более реалистичный подход — составление черновых вариантов документации на каждом этапе жизненного цикла API.

Планирование

Разработчики, применяющие подход code-first («сначала код»), часто упускают этап планирования, важный для успеха любого проекта. На этом этапе решаются следующие вопросы.

  • Какие данные пользователя будет запрашивать сервер?

  • В какие сроки должна быть выполнена работа?

  • Какие результаты ожидаются на каждом из этапов?

Кроме того, владельцы, архитекторы и разработчики API закладывают основы будущего продукта: определяют цели проекта, изучают целевую аудиторию и формулируют функциональные и нефункциональные требования к API.

Функциональные требования (functional requirements, FR) описывают возможности программного обеспечения, а нефункциональные (nonfunctional requirements, NFR) — его качественные характеристики. Например, при разработке поисковой системы функциональным требованием может быть возможность отправки поисковых запросов через API, а нефункциональным — возврат результатов поиска в течение одной секунды.

На этапе планирования необходимо ответить на следующие вопросы.

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

Какие устройства у пользователей API?
Это могут быть устройства интернета вещей (IoT-устройства), браузеры, мобильные телефоны или ИИ-агенты.

Есть ли требования к проектированию API?
Есть ли язык программирования или фреймворк, навязанный разработчиком API? Есть ли лимит времени, в течение которого API должен выполнить запрос? Зависит ли API от внешних сервисов?

Каков масштаб работы API?
Каково приблизительное количество пользователей?

Какую стратегию управления версиями использовать?
Можно выполнять версионирование по семантическому принципу или по дате выпуска версии.

Есть ли ограничения для API?
Влияют ли на функциональность API регуляторные ограничения, такие как GDPR или HIPAA?

Есть ли установленные каналы связи с пользователями API?
Как вы будете предоставлять пользователям документацию? Будет ли ограничен доступ к коммуникации?

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

ФУНКЦИОНАЛЬНЫЕ И НЕФУНКЦИОНАЛЬНЫЕ ТРЕБОВАНИЯ

На разных этапах жизненного цикла разработки ПО формулируются несколько типов требований к системе (https://oreil.ly/qvpIP): пользовательские, бизнес-требования, регуляторные, системные, архитектурные, функциональные, нефункциональные и требования к реализации.

Однако, с точки зрения проектировщика, на первых трех этапах жизненного цикла ключевую роль играют функциональные и нефункциональные требования (ФТ и НФТ соответственно). Разделение на ФТ и НФТ помогает расставлять приоритеты в проектировании и разработке, а также заранее выявлять риски, которые могут возникнуть из требований.

Рассмотрим определения ФТ и НФТ.

Функциональные требования (ФТ)
Конкретные функции, задачи или поведение системы. ФТ можно описывать с точки зрения пользователя, выполняющего определенные действия в системе, или с точки зрения самой системы. Например: «У пользователя должна быть возможность сбросить пароль» или «У администраторов должно быть право заблокировать пользователю доступ».

Нефункциональные требования (НФТ)
Возможности и ограничения, которым должна соответствовать система. Иными словами, НФТ описывают качество системы. Их также называют архитектурно значимыми требованиями, программными архитектурными характеристиками или атрибутами качества. НФТ описывают такие свойства системы, как развертываемость, сопровождаемость, производительность, безопасность и удобство использования (https://oreil.ly/s85Wq). Например: «Система должна быть быстрой» или «Система должна быть доступна 99,9 % времени».

Различие между ФТ и НФТ часто бывает размытым. Например, требование «Сервис должен предоставлять своевременные оповещения о погоде» может быть одновременно и функциональным, и нефункциональным:

• сервис предоставляет оповещения о погоде — это функция;

• сервис предоставляет своевременные оповещения — это качество реализации функции.

Если нужно определить, к какой категории относится требование, то ответьте на следующие вопросы.

• Связано ли требование с реализацией функции?

• Влияет ли требование на свойства системы (развертываемость, производительность и др.)?

• Сказано ли в требовании, что система или функция должна работать определенным образом?

• К каким данным относится требование — входным или выходным?

Система продолжает функционировать после этапа реализации, поэтому влияние НФТ проявляется не сразу.

Проектирование

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

ПОДХОД API-FIRST

Стратегия проектирования API-first предполагает, что разработка начинается с создания спецификаций API, собранных из требований организации и пользователей. Далее следует реализация. Этот подход полезен, если разработчики могут связаться с будущими пользователями и согласовать структуру API до реализации.

Как правило, спецификация API составляется в общепринятом формате, например OpenAPI (https://swagger.io) или AsyncAPI (https://www.asyncapi.com). Инструменты для работы с этими форматами помогают реализовывать и тестировать API, а также создавать документацию. Более подробно проектирование API рассматривается в главе 2.

Реализация

Этап реализации также называют фазой прикладной архитектуры (applied architecture phase).

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

Обратите внимание: реализация определяет фактическое поведение системы. Хотя детали реализации должны быть скрыты за интерфейсами, иногда они все же становятся видимыми.

API: ИНТЕРФЕЙС ИЛИ РЕАЛИЗАЦИЯ

Грегор Кицалес (Gregor Kiczales) в статье Towards a New Model of Abstraction in Software Engineering (https://oreil.ly/33Qqi) высказал идею о том, что абстракциям не всегда удается скрыть детали реализации, и это часто усложняет перенос системы:

«Абстракции», которыми мы пользуемся, на самом деле не являются абстрактными. За ними стоят реальные фрагменты кода, работающие на реальных компьютерах, потребляющих энергию и занимающих место в пространстве. Попытка игнорировать детали реализации подобна попытке игнорировать законы физики: звучит заманчиво, но в конечном счете ведет в никуда.

Грегор Кицалес (Gregor Kiczales), 1992

Эта идея известна как «Закон дырявых абстракций» (Law of Leaky Abstractions) (https://oreil.ly/mBLLI):

Любая нетривиальная абстракция в некоторой степени дырявая.

Джоэл Спольски (Joel Spolsky), 2002

Широко известен также закон Хайрама (Hyrum’s law) (https://www.hyrumslaw.com) о том, что детали реализации проявляются через интерфейс API:

При достаточном количестве пользователей API не имеет значения, что вы обещаете в контракте: все наблюдаемые изменения вашей системы будут зависеть от чьих-то действий.

Хайрам Райт (Hyrum Wright), 2012

«Дырявые» абстракции приводят к тому, что пользователи API начинают полагаться на поведение системы, которое разработчики не планировали и не документировали (такое поведение известно как «неявный интерфейс»)1. Это усложняет внесение изменений в API.

От практических решений, принятых на этапе реализации, зависит и безопасность API. Защищенные API создаются на основе механизмов шифрования, аутентификации, авторизации и других практик безопасного программирования, в том числе валидации входных и выходных данных (подробнее см. в разделе «Безопасность API» главы 2).

Тестирование

На данном этапе проверяется функциональность, безопасность и производительность API. За создание и проведение тестов отвечают разработчики и QA-команда (quality assurance). Тестирование может проводиться параллельно с реализацией, а его результаты могут влиять на другие этапы, например на проектирование, реализацию и развертывание.

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

Тесты можно выполнять вручную или автоматически, если они являются частью конвейеров непрерывной интеграции, поставки и развертывания (CI/CD) (см. подраздел «Развертывание» далее в этой главе). Запуск тестов в конвейере позволяет разработчикам оперативно выявлять проблемы в программном обеспечении и поддерживать его стабильное качество.

Интеграционное тестирование

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

Инструменты наподобие Docker (https://www.docker.com) упрощают настройку интеграционных тестов. Docker запускает изолированные контейнеры с необходимыми сервисами (например, базу данных, кэш или очередь сообщений). Это позволяет тестировать программное обеспечение на работающих копиях сервисов вместо использования заглушек (mocks), что делает результаты более реалистичными. Если сторонний сервис нельзя запустить локально, то можно настроить отдельный тестовый экземпляр и интеграционные тесты для взаимодействия с ним. Тесты будут проверять работу реального сервиса в контролируемой среде. Однако такая настройка часто приводит к непредсказуемым результатам и ошибкам тестирования, которые нельзя воспроизвести.

Если данные из продакшена разрешено использовать для тестирования, то сохраните ответ сервиса в файл (например, response.json) и используйте его в интеграционных тестах для эмуляции сервиса. Это позволяет проводить регулярные тесты (иногда называемые тестами записи и воспроизведения (record and replay)), избегая незапланированного взаимодействия с продакшен-средой.

Контрактное тестирование и фаззинг

Метод контрактного тестирования берет начало в работах Роберта У. Флойда (Robert W. Floyd). В конце 1960-х годов Флойд предложил проверять корректность работы программ с помощью логических утверждений. Этот и аналогичные, более поздние методы, такие как логика Хоара (https://oreil.ly/DAhnS; https://ru.wikipedia.org/wiki/Логика\_Хоара) (1969) и контрактное программирование (https://oreil.ly/KV5BZ; https://ru.wikipedia.org/wiki/Контрактное\_программирование) (1986), заключались в том, чтобы доказать, что программа будет работать правильно при допустимых входных данных:

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

Дональд Э. Кнут (Donald E. Knuth), 2003

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

Однако по аналогии с методом записи и воспроизведения можно сохранять набор прошлых запросов и ответов и проверять их соответствие спецификации API (параллельно с проверкой текущего взаимодействия провайдера и пользователя). Такой подход к контрактному тестированию схож с регрессионным тестированием (https://oreil.ly/wwfCo; https://ru.wikipedia.org/wiki/Регрессионное\_тестирование): он позволяет убедиться в том, что контракт API остается стабильным и пользователи и провайдеры продолжают его соблюдать. Например, при интеграции в процесс разработки контрактное тестирование позволяет обнаружить, что изменения со стороны провайдера несовместимы с поддерживаемыми версиями пользователей. Кроме того, тестирование позволяет определить, возможно ли удалить поле, которое используется только устаревшими версиями пользовательских приложений.

Контракт может составлять как потребитель API, так и провайдер. Соответственно есть два типа контракта: управляемый потребителем (consumer-driven contract, CDC) и управляемый провайдером (provider-driven contract, PDC). В CDC поведение сервиса определяет потребитель, а задача провайдера — реализовать контракт в API. Этот подход требует больше усилий от провайдера. В PDC усилия распределяются иначе: контракт определяет провайдер, а потребитель следует ему.

Основное ограничение контрактного тестирования заключается в том, что не всегда возможно собрать достаточно большой набор запросов и ответов, чтобы оценить соблюдение контракта API. Сбор входных данных осложняется при использовании популярного метода защитного программирования (defensive programming) (см. врезку «Защитное программирование» в подразделе «CRUD» в главе 5). В этом методе приоритет отдается обработке ошибок и оперативному восстановлению функциональности, вследствие чего спектр «допустимых» входных данных и шаблонов поведения, поддерживаемых API, расширяется. Этот подход противопоставляется так называемому «атакующему» программированию (offensive programming или fail-fast), в котором программа прекращает работу при получении некорректных входных данных.

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

Сквозное тестирование

Такое тестирование (end-to-end) предполагает имитацию взаимодействия пользователя с системой. Цель — проверить работоспособность системы в целом. Традиционно сквозные тесты проводились вручную. Такие инструменты, как Cypress (https://www.cypress.io), Playwright (https://playwright.dev) и Selenium (https://www.selenium.dev), позволили автоматизировать этот процесс, однако результаты их работы не всегда стабильны.

Квадранты Agile-тестирования

Разработчики создают множество разных типов тестов. Чтобы классифицировать имеющиеся подходы к тестированию, используется диаграмма «Квадранты Agile-тестирования» (рис. 1.8). На горизонтальной оси расположены цели тестирования — от поддержки команды в разработке до критики продукта. Вертикальная ось показывает направленность тестирования: от технической составляющей продукта до удобства использования.

Рис. 1.8. Квадранты Agile-тестирования
Рис. 1.8. Квадранты Agile-тестирования

Поясним назначение каждого квадранта.

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

Q2
Тестирование ориентировано на улучшение пользовательского опыта и поддержку команды разработки. Тесты проверяют функциональность, гарантируя, что система удовлетворяет потребности пользователей. Допускается как автоматизированное, так и ручное тестирование.

Q3
Тестирование ориентировано на потребности пользователя и критику продукта. Здесь обычно проводят приемочные тесты (user acceptance tests, UAT), которые выявляют проблемы, пропущенные при разработке, и улучшают пользовательский опыт. Основной недостаток UAT — их часто приходится выполнять вручную.

Q4
Тестирование ориентировано на совершенствование технологий и критику продукта. Тесты здесь имеют технический характер и проверяют соблюдение НФТ, таких как безопасность и производительность. Для их проведения часто требуются специализированные инструменты.

Таким образом, тесты в квадрантах Q1 и Q2 поддерживают процесс разработки, контролируя соблюдение функциональных требований. Тесты в квадрантах Q3 и Q4 оценивают продукт с точки зрения соответствия потребностям пользователей и соблюдения нефункциональных требований. Эта модель Agile-тестирования служит своего рода картой, которая охватывает основные виды тестирования, позволяющие создавать качественные и удобные в сопровождении приложения.

Развертывание

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

Первый вопрос: как будет организована команда, управляющая развертыванием? Будет ли разделение на команды разработки и эксплуатации или вы выберете подход DevOps, где эти две команды работают вместе? DevOps позволяет создавать конвейеры, где интеграция (сборка), доставка (выпуск) и развертывание ПО являются этапами единого, непрерывного процесса.

На рис. 1.9 показаны этапы развертывания API, а также связи между конвейерами CI/CD.

Рис. 1.9. Конвейеры CI/CD
Рис. 1.9. Конвейеры CI/CD

Рассмотрим роли каждого типа конвейеров.

  • Непрерывная интеграция — это конвейер сборки артефакта, состоящий из таких этапов, как:

    • линтинг — проверка соответствия исходного кода стандартам программирования;

    • статический анализ кода — предотвращение добавления в код нежелательных, сложных или небезопасных паттернов программирования (например, жестко запрограммированных секретов или инъекций кода);

    • анализ зависимостей — проверка кода на наличие потенциально устаревших или нелицензированных библиотек;

    • сборка — создание артефакта;

    • тестирование — проверка функциональности артефакта;

    • проверка безопасности — проверка собранного артефакта на уязвимости и выполнение автоматизированного пентеста.

Результат работы конвейера CI — артефакт, например образ контейнера, нативный двоичный файл или платформенно зависимый пакет. Готовый артефакт доставляют в целевой репозиторий: в Docker Hub (https://hub.docker.com), GitHub Packages (https://oreil.ly/80QID), JFrog Artifactory (https://oreil.ly/iejv0) или на FTP-сервер классического типа.

  • Непрерывная поставка — это конвейер, который запускается по завершении CI-конвейера. После ручного подтверждения он развертывает собранный артефакт в нужную среду. Стратегия развертывания (https://oreil.ly/4hw1Y) зависит от таких факторов, как степень сложности API, организационные требования и возможности инфраструктуры. К популярным стратегиям относятся сине-зеленое (blue-green deployment) и канареечное развертывание (canary deployment).

  • Непрерывное развертывание — этот конвейер автоматически развертывает артефакты в нужную среду, обходясь без участия человека. На данном этапе применяются автоматические тесты, среди которых сквозные (end-to-end), дымовые для проверки наиболее важной функциональности, нагрузочные и стресс-тесты.

Помимо описанных технических характеристик, в методологии DevOps культивируется сотрудничество между командами разработки и эксплуатации, а также совместная ответственность за жизненный цикл продукта. Проблемы безопасности команды DevOps решают по принципу shift-left: требования безопасности находятся в фокусе внимания с первых этапов жизненного цикла продукта, а не только на завершающем этапе (shift-right). Такой подход называют DevSecOps.

В анонимной цитате из интернета справедливо отмечается: «shift-left повышает трение в команде, а shift-right повышает корректность разработки». Увеличение нагрузки на разработчиков снижает их продуктивность в плане создания новых функций ПО. При частых сбоях проверок безопасности команды могут отключать эти проверки, что снижает эффективность подхода shift-left.

Методология DevOps основана на автоматизации: считается, что перенос операционных задач на более низкий уровень (например, включение проверок безопасности в базовую платформу) снижает нагрузку на разработчиков (https://oreil.ly/153p3). Однако существование отдельных команд DevOps или DevSecOps говорит о том, что некоторые идеи движения DevOps трудноосуществимы, поскольку один разработчик не справится со всеми возложенными на него задачами.

После сборки артефакта API возникает вопрос о месте его развертывания. Это классическая дилемма «купить или создать» (buy-versus-build). В зависимости от потребностей артефакт API можно развернуть на проприетарной облачной платформе, на собственном облачном сервере или на локальных компьютерах. Если вы выбрали путь «создать», то готовы ли вы нести высокие затраты на настройку и поддержку платформы типа Kubernetes (https://kubernetes.io), которая поддерживает высокодоступную инфраструктуру для развертывания и масштабирования контейнеризованных приложений? Или вы предпочтете более низкие первоначальные затраты на простой инструмент наподобие Kamal (https://kamal-deploy.org), понимая, что в будущем это может привести к более высоким затратам из-за необходимости управлять мощностями вручную?

Дилемма «купить или создать» затрагивает не только исходную цель развертывания, но и другие сервисы, поддерживающие операции через API. Необходимо расставить приоритеты. Будет ли выгоднее использовать интегрированную проприетарную систему облачного провайдера, у которого реализованы сервисы прокси-сервера, логирования, управления ключами и информационной безопасности? Или лучше развернуть собственное, более контролируемое решение на основе компонентов с открытым исходным кодом или разработанных внутри компании?

Следующий вопрос касается количества сред для развертывания API. Продакшен-среда — это место, где API работает, но тестирование в ней может быть запрещено по требованиям комплаенса. Развертывание изменений напрямую в продакшен-среду без тестирования рискованно, поэтому перед развертыванием артефакта API тесты запускаются в тестовой или стейджинг-среде. Кроме того, может потребоваться одна или несколько отдельных сред разработки или функциональных сред для проведения потенциально разрушительных экспериментов, чтобы избежать блокировки доступа к общей промежуточной среде.

При работе с несколькими средами нужно также определиться, какую стратегию ветвления использовать в системе контроля версий.

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

Стейджинг-среда — это не продакшен и никогда им не будет.
Чарити Мэйджорс (Charity Majors), 2019

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

Сопровождение

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

На рис. 1.10 показана традиционная классификация типов сопровождения ISO/IEC/IEEE 14764 (https://oreil.ly/8V2mi), основанная на характере изменений, вносимых в ПО. Запрос на изменение подразумевает либо исправление ошибок, либо улучшение системы. Корректирующий запрос связан с устранением дефектов программного обеспечения, а запрос на улучшение — с изменением имеющихся функций или добавлением новых.

Рис. 1.10. Классификация типов сопровождения по стандарту ISO/IEC/IEEE 14764
Рис. 1.10. Классификация типов сопровождения по стандарту ISO/IEC/IEEE 14764

Рассмотрим пять типов сопровождения, возникающих в результате запроса на изменение.

Корректирующее
Устраняет сбои в работе ПО, вызванные ошибками. Требует значительных затрат и может занимать много времени. Разновидность корректирующего — аварийное сопровождение, которое требует внесения внеплановых изменений для поддержания работоспособности системы.

Превентивное
Предполагает предотвращение сбоев ПО за счет их прогнозирования. Сопутствующий прием — омоложение программного обеспечения (software rejuvenation), связанное с устранением накопленных ошибок и оптимизацией системных ресурсов.

Адаптивное
Связано с внесением исправлений или улучшений в среду работы ПО. Необходимость такого сопровождения обусловлена тем, что среда, в которой функционирует программное обеспечение, подвержена изменениям.

Дополняющее
Наиболее распространенный тип сопровождения, связанный с необходимостью добавить новую функциональность или улучшить имеющуюся.

Совершенствующее
Предполагает усовершенствование ПО для повышения его производительности, удобства сопровождения и улучшения пользовательского опыта. Может выполняться тонкая настройка ПО (software tuning) для устранения узких мест производительности и рефакторинг для повышения удобства сопровождения кода.

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

Итак, мы рассмотрели этапы жизненного цикла, ведущие к созданию API: планирование, проектирование, тестирование, реализацию, развертывание и сопровождение. В следующем подразделе поговорим о выводе API из эксплуатации, в том числе из-за его устаревания.

Вывод из эксплуатации

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

При отсутствии плана вывода API из эксплуатации в инфраструктуре организации появится так называемый зомби-API (zombie API) — тот, который больше не поддерживается, но остается активным, и к нему можно получить доступ. Зомби-API представляют серьезную угрозу для безопасности организации.

С другой стороны, команда разработчиков и репутация организации могут пострадать и в случае неправильного вывода API из эксплуатации.

Для этого этапа разрабатывается план миграции, позволяющий поддерживать параллельную работу старой и новой версий API. Кроме того, создается план завершения жизненного цикла, определяющий, как объявить API устаревшим, не повлияв на текущую производительность, и как сообщить пользователям о выводе API из эксплуатации.

Объявление API устаревшим означает, что он будет доступен еще какое-то время, но его удаление (или замена) уже запланировано. Устаревание API тесно связано с частотой новых релизов. Например, организация может придерживаться политики поддержки максимум двух версий — тогда при выпуске третьей первую удалят. Допустим, она выпустила две версии API — v1 и v2, а теперь готовит третью — v3. Это значит, что при выпуске v3 версию v1 удалят.

Устаревание и вывод из эксплуатации привязаны к конкретным датам. Дата устаревания указывает момент, начиная с которого поддержка обновлений API и исправление ошибок ограничиваются. Дата вывода из эксплуатации означает момент, с которого API становится недоступен.

Если организация планирует объявить API устаревшим, то необходимо уведомить об этом пользователей. Например, в Kubernetes (https://kubernetes.io) при создании устаревшего артефакта через CLI выводится предупреждающее сообщение (рис. 1.11).

Рис. 1.11. Уведомление об устаревании API Kubernetes
Рис. 1.11. Уведомление об устаревании API Kubernetes

Уведомить пользователей можно, разместив баннер на сайте с документацией. На рис. 1.12 показано предупреждение об устаревании API PaLM от Google.

Рис. 1.12. Баннер с уведомлением об устаревании API
Рис. 1.12. Баннер с уведомлением об устаревании API

Еще один вариант — добавить заголовки об устаревании API в ответ (пример 1.4).

Пример 1.4. HTTP-заголовки устаревания и завершения поддержки

Sunset: Wed, 11 Nov 2026 11:11:11 GMT
Deprecation: @1688169599
Link: <https://developer.example.com/deprecation>; rel="deprecation"

Метка времени в заголовке Deprecation может указывать как на прошедшую, так и на будущую дату. Прошедшая означает, что API уже устарел. Однако дата в заголовке Sunset всегда указывает на будущее, обозначая момент прекращения поддержки API. Период завершения поддержки публичного API обычно занимает несколько месяцев. Кроме того, в заголовке Link может содержаться дополнительная информация об устаревании API, например ссылка на документацию.

Помимо даты прекращения поддержки, в сообщение об устаревании можно добавить контактные данные, руководство по миграции или даты выпуска следующей версии, если они известны.

Информацию об устаревании и прекращении поддержки API может потребоваться сохранить для комплаенс-аудита или исторических справок.

Управление, администрирование и платформа API

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

Управление — это набор формальных и неформальных правил и процессов, которые направляют и контролируют деятельность организации. Соблюдение этих правил обеспечивают управляющие структуры организации.

Управление API, в свою очередь, предполагает создание регулирующих стандартов и политик, их распространение среди команд API и внедрение в сами API. Контроль соблюдения политик выполняется за счет мониторинга API и деятельности команды.

Отсутствие управления приводит не только к несогласованности в работе API, но и к появлению теневых API (shadow APIs), которые активно используются, но не управляются, не документируются и развертываются без официального контроля организации. Управление же способствует безопасности, стабильности, позволяет повторно использовать API и обеспечивает их соответствие регулирующим политикам.

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

Платформа API — это программное обеспечение для систематизации, управления и администрирования API, а также для взаимодействия с пользователями. Набор инструментов платформы позволяет командам разработчиков создавать и публиковать API, управлять ими и использовать их. Платформа API интегрируется с внешними инструментами, такими как конвейеры CI/CD, облачная инфраструктура, инструменты мониторинга, а также средства безопасности и комплаенса. Среди распространенных платформ API — Amazon API Gateway (https://oreil.ly/t87B6), Azure API Management (https://oreil.ly/LBZhB), Google Cloud Apigee (https://oreil.ly/FXFVz), Kong (https://konghq.com) и MuleSoft Anypoint Platform (https://oreil.ly/4JbwO).

API Landscape (https://apilandscape.apiscene.io) — это сайт с инструментами для проектирования, разработки и управления API. Пусть вас не смущает их огромное количество — многие из инструментов встречаются в списке несколько раз.

Будущее API

Закончить обсуждение истории и основ API логично взглядом в будущее.

По данным Statista, в 2024 году количество подключенных IoT-устройств достигло 18 млрд. Из них 7,2 млрд приходятся на подписки на смартфоны, которые приобрело около 67,1 % населения мира. Ожидается, что в ближайшие годы количество IoT-устройств будет расти, а для реализации многих функций этих устройств необходимы сетевые API.

Провайдер CDN (Content Delivery Network) Cloudflare в отчете по безопасности API за 2024 год (https://oreil.ly/Q0QLD) сообщает, что 60 % динамического (некэшируемого) трафика приходится на API. Кроме того, API стали самой быстрорастущей категорией трафика в Cloudflare.

Еще одна причина возрастающего спроса на API — развитие ИИ и LLM. Обучение больших языковых моделей предполагает использование большого объема данных — текстов, изображений, аудио и видео, которые в основном поступают через API. По мере того как компании создают собственные сервисы на основе LLM, новые и имеющиеся стили API будут способствовать их развитию, выступая в роли «воронок» для входящих и исходящих данных.

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

По мере развития ИИ и увеличения количества IoT-устройств ключевым элементом API станет обеспечение безопасности. По прогнозам компании Gartner, сделанным в 2021 году, самым распространенным видом атак на корпоративные веб-приложения станут атаки на API (https://oreil.ly/52qic). В отчете Kong за 2023 год (https://oreil.ly/Xoayu) прогнозируется, что к 2027 году количество атак на API по всему миру возрастет более чем в два раза.

Для обеспечения безопасности API создаются новые протоколы и совершенствуются имеющиеся. В июне 2022 года вышла третья версия протокола HTTP (HTTP/3) (https://oreil.ly/3CK30). Для устранения недостатков WebSocket был создан протокол WebTransport (https://oreil.ly/GSqqu). Протокол MCP (Model Context Protocol) (https://oreil.ly/5uKl4) призван упростить поиск и использование данных LLM и агентным ИИ.

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


Оформить предзаказ на книгу: «Стили API. Проектирование и внедрение» можно на нашем сайте.

Скидка 35% по промокоду - Предзаказ

Комментарии (0)