API - это контракт описывающий взаимодействие двух и более систем, как с позиции внешнего, так и с позиции внутреннего использования. API - это наиболее эффективный способ управления сложностью реализуемой системы, проведению ее архитектурных границ, изоляции данных и реализации требований безопасности. Пректирование хорошего API требует выполнение нескольких ключевых этапов, о которых я хочу поговорить в данном стриме.
Разработка программного обеспечения как правило сводится к подходу ориентированному на данные. Практически все API строятся вокруг источников данных (как правило СУБД) и носят ресурсо-ориентированный характер, существуют исключения в виде API обеспечивающих работу системы, как правило это хорошо стандартизованная часть, которая тиражируется из проекта в проект, в рамках обеспечивающих функций рассматриваются вопросы управления доступом к ресурсам и тому подобные задачи.
API с позиции состояний:
- с сохранением состояния (серверный стейт);
- без сохранения состояния (без серверного стейта).
API c позиции стиля работы:
- Remote Procedure Call (RPC) - удаленный вызов процедур, один из самых используемых стилей при построении API. Он реализуется с помощью клиент-серверного шаблона архитектуры, и позволяет клиенту выполнять свой код удаленно на сервере. Обычно используют компактные бинарные форматы. Пример: gRPC ( https://grpc.io ), из более ранних примеров - SOAP
- Remote method invocation (RMI) - вариант RPC который "скрывает" удаленную природу вычислений и со стороны клиента выглядит так, будто вычисления выполняются локально.
- REpresentational State Transfer (REST) - набор прицнипов для построения легковесных API, как правило использует текстовый формат для обмена сообщениями (JSON, XML). Текстовый формат сообщений позволяет развязать зависимости сервера и клиента, не использовать какие-либо общие библиотеки. Унифицирован для веб-разработки.
- специализированные API - как правило API построенные на каком либо языке запросов, которые разрабатываются конкретно под сервер. Пример: SQL.
- Наиболее распространено семантическое версионирование MAJOR.MINOR.PATH-LABEL+MetaInfo MAJOR - обратно несовместимые изменения MINOR - обратно-совместимые изменения PATCH - локальные изменения
- API должны учитывать совместимость:
- по версии клиента (должен поддерживать все клиенты предыдущего API)
- по версии сервера (должен работать на серверах поддерживающих предыдущий API)
- по версии протокола (должен поддерживать все протоколы, что и предыдущий API) Если хотя бы одно условие нарушается, увеличивается MAJOR версия.
- Документированность
- Выразительность
- Простота
- Законченность
- Версионная целостность
- Предсказуемость
Проектирование API - это проектирование самостоятельного, логически законченного "безголового" приложения, т.е. приложения, которое получает на вход данные и выдает результат в том или ином распространенном формате обмена. Проектирование API это процесс, который может быть выстроен как стандартизованный итеративный процесс, состоящий из следующих основных атрибутов:
- Описание задачи
- Сбор требований
- Разработка архитектурной перспективы
- Детализация до уровня кода
Моменты на которые обычно следует обратить внимание:
- Именование (непротиворечивость, простота, краткость и т.д.);
- Формат данных (промежуточные состояния, сериализация, частные/единичные случаи, проблемы "потеряшек" - null и прочие, ограничение примитивов)
- Описание ресурсов (таблицы, отношения, представления, диаграммы и т.д.);
- Идентификация ресурсов (уникальность ключей, идентификация на основе кортежей, UUID)
- уникальность (решение проблемы похожести)
- воспроизводимость
- безопасность (генерация на основе реальной энтропии)
- Идемпотентность;
- Фоновые процессы;
- Масштабируемость (частичное использование, пагинация, сдвиги по данным, "долгие"-запросы);
- Веб-ориентация (get, post, put, delete).
При разработке API важно предусмотреть возможность горизонтального масштабирования, для этого обязательно на стадии раннего проектирования предусмотреть точки подключения мониторинга (систем автоматизированного управления).
Наиболее часто мониторинг реализуется:
- на базе логов (важно иметь сквозную идентификацию всех запросов, обрабатывающихся в рамках цепочки API);
- отдельных точек подключения с собственными форматами данных (получение данных по запросу);
- шин обмена данными (специальная шина сообщений, в которой идет timeseries данные мониторинга, часто реализуется на базе MQ решений).
Основные способы обеспечения безопасности:
- Шифрование
- Аутентификация (подтверждение, что "я" есть "я")
- Авторизация (что "я" могу)
- Квоты на использование ресурсов
- Аудит действий
Аутентификация:
- Пароль
- Bearer токен (cookie, JWT, заголовки HTTP)
- Сертификат
Авторизация:
- ACL
- Roles
- Атрибуты (ABAC)