Статьи

Лучшие практики для создания SDK для API

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

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

Инициализируйте SDK безопасно и асинхронно

Для большинства SaaS-решений с SDK вашему пользователю потребуется инициализировать SDK и передать ключ API. Вам может потребоваться получить определенную информацию об учетной записи с ваших серверов или такую ​​информацию об устройстве, как версия ОС. Эта работа должна выполняться в фоновом потоке или использовать асинхронные вызовы. Используя фоновые потоки, основной поток может продолжать отвечать без передачи. В зависимости от того, предназначен ли ваш SDK для внешних или внутренних частей, основной поток может быть основным потоком пользовательского интерфейса или потоком, отвечающим на входящие HTTP-запросы.

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

Пакетный интенсивный сетевой трафик

Для любого HTTP-соединения, созданного с другим сервером, перед передачей данных могут возникнуть некоторые издержки. Это включает в себя взаимный обмен пакетами SYN и ACK между клиентом и сервером для создания соединения TCP, рукопожатие для установки SSL / TLS и т. Д. Вместо того, чтобы повторять их для каждого HTTP-запроса, вы можете повторно использовать соединения через Keep-Alive .

Кроме того, чтобы сохранить работоспособность, вы можете объединить несколько событий или команд в один исходящий HTTP-запрос. Возвращаясь к нашему примеру SDK аналитики, было бы неэффективно делать HTTP-запрос для каждого клиентского события, которое должно быть зарегистрировано. У самого TCP есть издержки, и вы также отправляете много HTTP-заголовков для каждого запроса для обработки аутентификации, кэширования и т. Д. Пакетная обработка уменьшает эти издержки и уменьшает количество системных вызовов, сохраняя все данные в одном и том же буфере памяти.

Пакетирование выполняется путем отправки массива событий или команд, а не по одному на HTTP-запрос. Обычно это лучше всего работает в сочетании с локальной очередью.

Использование локальной очереди

Чтобы правильно реализовать некоторые из вышеперечисленных функций, таких как пакетирование, вы можете использовать локальные очереди. Локальная организация очереди отделяет логику, используемую для сбора или обработки данных, от логики, необходимой для пакетной обработки и отправки их на сервер. События могут храниться в очереди памяти в памяти или записываться на диск для обеспечения долговечности, если существует риск отключения питания. Более сложная архитектура очередей может использовать распределенные хранилища данных, такие как Redis, хотя это усложняет настройку SDK, поэтому не рекомендуется, если в этом нет необходимости.

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

Промывка очереди

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

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

компрессия

Сжатие очень легко использовать, но его легко забыть. Не все клиентские библиотеки HTTP сжимают полезные нагрузки по умолчанию, и ваш бэкэнд должен поддерживать предпочитаемую (де) кодировку сжатия. Сжимая полезную нагрузку в виде gzip с использованием zlib или аналогичного, вы можете уменьшить размер полезной нагрузки более чем в 10 раз по сравнению с обычным текстом. Вы также можете посмотреть на новые форматы, такие как Brotli, которые могут еще больше уменьшить это на 10-20% по сравнению с gzip.

Установить User-Agent

Вы должны включить как имя SDK, так и версию в User-Agentзаголовок HTTP. Это позволяет понять принятие SDK и соотнести проблемы с конкретными версиями. Например, мы в Moesif приняли стандартный формат libraryname/semvarдля наших SDK так:


HTTP