В своей практике мы используем JSON-RPC 2.0 как при внешнем, так и при
внутреннем взаимодействии.
Современные приложения и сервисы работают в RPC парадигме, нежели в ресурсной.
REST используется там, где JSON-RPC 2.0 не сильно подходит: например, работа с файлами (скачивание и загрузка).
Внешние системы так же реализуют входящие вебхуки, которые нужно обработать (обычно это REST).
Запускает go generate – генерируется необходимый файл для zenrpc сервера.
После этого разработчик получает:
Готовую схему с документацией (из кода)
UI для проверки сервиса (который использует схему)
Генераторы клиентов под различные языки (Go/JS/Swift/Kotlin/Dart/PHP) - отдает клиентам уже готовые библиотеки.
Тулинг для сравнения схем при деплое
RPC Endpoint
Используйте соглашения для внешнего и внутреннего API:
/v1/rpc/ – внешнее, доступен префикс сервиса /v1/ наружу через nginx.
/int/rpc/ – внутренее, при межсервисном взаимодействии.
Поддерживайте обратную совместимость до последнего, чтобы не пришлось поднимать версию.
Вместо поднятия версии делайте новые методы и плавно переходите на них на всех клиентах.
/v1/rpc/: метод app.Settings
Полезным методом в API, который стоит заложить в начале создания сервиса, является app.Settings. Он определяет поведение клиентов (внешнее API):
readonly – находится ли приложение в режиме “только чтение”.
maintenance - доступно или недоступно приложение сейчас. Если true, то надо показать экран недоступности приложения с кнопкой попробовать снова (которая перезапросит app.Settings и проверит флаг)
features – с помощью этой структуры можно включать или выключать определённые фичи.
versions - semver
minVersion - минимальная работоспособная версия приложения. Если приложение меньше этой версии, то оно не работает и просит обновиться (с кнопкой обновиться, стор?).
warningVersion – показать нотис, то неплохо было бы обновить приложение.
invalidVersions – массив заблокированных версий, поведение такое же, как с minVersion.
Использование API клиентами
Клиентами могут быть сервисы, браузеры, nodejs процессы и мобильные приложения.
Если мы говорим про внешнее API, то хорошей практикой является разделить хосты API у сайта и приложений.
Важно сохранять cookies от сервера между запросами, потому что в них может быть ценная информация (nginx user id, ddos
guard cookies, captcha validation, etc…)
Дополнительные заголовки
Клиенты должны передавать следующие заголовки, а сервер должен их логировать:
X-Request-Id: сквозной заголовок, который помогает отследить запрос между всеми системами и сервисами. Если ничего
не передано, то обычно назначается автоматически.
Конечно же, можно расширить этот список для лучшей идентификации запросов.
Если используется система трекинга ошибок (например Setnry), то данные параметры тоже необходимо прокидывать в нее.
Формирование User Agent
Для мобильных клиентов: <приложение>/<версия> (<версия ОС>; <версия устройства>) [версия библиотеки]
Добавляем в Get параметр вызываемый метод в method или methods
Примеры:
/v1/rpc/?method=app.Settings – для одиночного запроса
/v1/rpc/?methods=app.Settings,app.Dict – для batch вызовов
Итог
Сохранять куки между запросами
Передавать дополнительные заголовки: Platform, Version, X-Request-Id
Передавать сформированный User-Agent
в API URL добавляем GET параметром вызываемые методы
Безопасность с API
Если API доступно в Интернете, то его наверняка попытаются использовать так, как вы не планировали.
Для мобильных клиентов можно
использовать SSL Pinning, это затруднит
исследование, но оно все еще возможно.
Поэтому проектируйте API таким образом, что о нем знает весь мир. Достоверно понять, что API использует легитимный
клиент, практически невозможно.
Для реализации проверки подлинности клиента используется техника подписи запросов. Но и это не дает 100% гарантии.
Вот список простых правил, которые помогут добиться минимальной безопасности:
Используйте лимиты (не должно быть возможности выбрать всю базу целиком за один запрос).
Проверяйте пользовательский ввод (пользователь всегда не прав).
Используйте SSL Pinning в мобильных клиентах.
Используйте подпись запросов для критичных методов.
Мониторинг работы API
Чтобы понять, что API используется не так, как вы планировали, существуют метрики.
В библиотеке zenrpc они собираются по умолчанию. По ним необходимо настроить алертинг и смотреть dashboard.
Комбинации заголовков Platform/Version и UserAgent помогут базово определить нелегитимный трафик.