API Style Guide, или не заставляйте пользователей думать
Привет! Меня зовут Лёша Руцкой, и я — продуктовый менеджер в компании Wrike. До этого работал в Adform и PandaDoc. Последние пять лет я занимаюсь всем, что связано с интеграциями и API.
Wrike — это SaaS продукт для совместной работы и управления проектами. Мы хотим, чтобы разработчики строили свои решения на базе Wrike, а для этого нужно, чтобы наш API был удобным. При этом у нас 9 офисов по всему миру, и 3 из них — офисы разработки. Довольно сложно создавать консистентный API силами распределённых команд, которые говорят на разных языках. Растёт вероятность того, что их решения начнут противоречить друг другу. В этом случае не обойтись без единого для всех набора правил.
Если вы тоже работаете распределённо и делаете свой API, то API Style Guide может вам помочь. Я хочу рассказать, какие распространённые проблемы он решает и как облегчает жизнь разработчикам. Также поделюсь своим опытом по написанию и внедрению собственного API Style Guide в компании.
Зачем нужен удобный API?
Многим читателям наверняка приходилось решать проблемы с помощью не самого удобного API. Да, это не очень просто и занимает больше времени, но обычно всё-таки проблему решить можно.
Тогда зачем тратить время и усилия команды на то, чтобы сделать API лучше? Ответ достаточно прост: очень часто решение по поводу использования вашего продукта принимают разработчики, особенно если речь идёт об API и интеграциях. Поэтому важно задумываться не только про user experience (UX), но и про DX — developer experience.
Приведу пример. Когда-то я работал в команде, которая отвечала за все интеграции продукта. Часто в середине квартала, когда у нас уже были намечены планы, приходил маркетолог и говорил: «Компания Z сделала новый маркетплейс и релизит следующую версию своей платформы. Скоро у них будет крутое публичное мероприятие, на котором мы можем рассказать про нашу интеграцию и успехи! Будет здорово, если мы сейчас быстренько напишем эту интеграцию». Как мы поступали в таком случае? Если опытный разработчик в команде мог за три дня сделать минимальный работающий прототип, то чаще всего за две-три недели мы успевали довести задачу до идеального состояния. Если нескольких дней не хватало, значит API и документация были так себе. Перекраивать планы и браться за новую интеграцию для нас было бессмысленно — всё равно к установленному сроку ничего путного не получилось бы. Помните, что и ваш продукт может находиться в такой ситуации — партнёры будут решать, стоит ли иметь с вами дело в зависимости от того, насколько быстро и удобно можно начать работу с вашим API.
Но ведь вряд ли кто-то хочет спроектировать плохой API. Почему же у всех получается по-разному? Обычно API развивается так. Когда стартап начинает расти и к нему приходят первые клиенты, одна из команд делает свой endpoint и решает передавать версию в URL:
Постепенно появляются новые клиенты и новые потребности. В работу включаются ребята из второй команды, которые считают, что для версионирования лучше использовать собственные Media types:
Через некоторое время приходит третья команда. На одной из конференций они узнают, что Stripe версионирует свои API датами мажорных релизов. И решают сделать также:
В итоге получается API, в котором есть три метода версионирования. Все методы работают, но работают по-разному.
Мне, как разработчику, было бы неудобно пользоваться таким API. И причина не в том, что я предпочитаю один подход к версионированию всем остальным. Просто использовать несколько способов одновременно — неудобно. Придётся три раза написать код, который работает с API, или использовать три разные библиотеки. А это значит, что и ошибок будет в три раза больше.
А ещё есть даты и время. Даже при использовании стандартного подхода данные можно передавать по-разному: по часовому поясу вашего сервера, по Гринвичу, по времени на клиенте, в Unix time. Клиентам надо будет приводить все данные к одному формату.
Сообщения об ошибках вообще все делают по-разному. Например, так:
Или так:
Есть ещё моё любимое сообщение об ошибке:
Ну и просто классика — ответ 200 OK, внутри которого лежит JSON c описанием, что же пошло не так.
На мой взгляд, самое главное в хорошем API — это консистентность. Неважно, какой именно подход к версионированию вы выберете, главное, чтобы он был одинаковый во всём API. Ещё более удачным решением будет взять популярный подход, которым уже пользуются другие компании. Скорее всего, ваши клиенты уже с ним сталкивались, и у них есть готовый код или библиотека. Не нужно лишний раз думать, можно использовать готовые инструменты.
Единый подход к созданию API особенно важен для больших компаний, в которых есть распределённые команды. Если десять человек в комнате создают стартап, то каждый разработчик может просто постучать соседа по плечу и договориться или увидеть основные проблемы во время code review. В большой компании это становится сложнее.
API Style Guide поможет вам решить такие проблемы. Это документ, который описывает принципы дизайна вашего API. Если все используют одни и те же подходы, то создаётся впечатление, что API разрабатывал один человек, а не множество разных команд. Этот подход во многом похож на Code Style Guide, когда команды договариваются о том, как они пишут код. Человек из одной команды может посмотреть кодовую базу другой команды и быстро понять, что там происходит.
Как сделать свой API Style Guide?
Arnauld Lauret (известен как API Handyman) создал классный сайт — API Stylebook. Он собрал публично доступные Style Guide, которые разные компании (Cisco, Google, Red Hat, государственные учреждения и многие другие) выложили в открытый доступ.
На сайте гайдлайны разбиты по темам. Например, если вас интересует версионирование, то на вкладке «Versioning» можно узнать, как разные компании решают эту проблему.
Учитесь на опыте других! Но полностью копировать чужой Style Guide — не самая хорошая идея. Всё-таки он решает проблемы другой компании, а не вашей.
В свой Style Guide вам стоит добавить темы, которые близки именно вашей компании и решают именно ваши проблемы. Может быть, у вас много мобильных приложений, и для вас важен размер ответа. Тогда опишите принципы, связанные с этим аспектом. Или вы договорились с внутренними командами о том, что пора распиливать монолит на микросервисы, которые будут общаться друг с другом через Message Broker. В этом случае в API Style Guide нужно включить принципы, по которым вы собираетесь использовать Kafka или какой-то другой инструмент.
Что ещё включить в API Style Guide
Также в Style Guide стоит включить базовые ценности и инженерные подходы, которых придерживается компания.
Какими они могут быть?
- Write APIs in English. Это точно стоит делать, если в компании есть большие распределённые команды. Даже если сегодня все ваши коллеги говорят по-русски и внутренняя документация написана на русском, это не значит, что через пять лет у компании не будет офиса в другой стране и удалённых сотрудников. Все публичные и приватные Style Guide, с которыми я знаком, написаны на английском.
- Следуйте API First principle. Сначала спроектируйте API и договоритесь о его использовании со всеми возможными потребителями: соседними командами, пользователями, frontend-командой. Все вовлечённые стороны могут обсудить, насколько предложенный API подходит для решения проблем. И сделают они это до того, как код окажется в проде, а значит и исправить ошибки можно будет раньше и дешевле.
- Используйте REST и JSON. Это может быть важно, если вы хотите, чтобы вашим API или платформой пользовалась максимально широкая аудитория. Несмотря на то, что с 2017 года GraphQL становится всё более популярным, далеко не все о нём знают. Многие разработчики, скорее всего, им никогда не пользовались, а значит для них увеличится время на погружение и разработку. Зачем создавать сложности?
Дальше базовые принципы можно раскладывать на темы. Например, внутри принципа про использование REST и JSON можно легко установить, какие темы стоит описать в Guide:
- Prefer REST API with JSON payloads
- HTTP requests
- HTTP status codes
- JSON
Дальше по каждой теме вы можете придумать правила, которым должны следовать все команды в компании:
- HTTP requests
- MUST use HTTP methods correctly
- Custom HTTP headers SHOULD follow naming convention
Мне очень нравится подход, который описывает необходимость выполнения правил через глаголы MUST, SHOULD или MAY (позаимствовано из RFC 2119). Тогда каждый читающий Style Guide человек будет различать обязательные правила и рекомендации.
Вот как, например, это выглядит у Zalando:
О чём стоит помнить в начале работы над Style Guide
- Инструменты. В самом начале вы можете выбрать и описать стандартные инструменты, которыми будут пользоваться все команды. Например, шаблоны проектов для языков программирования и фреймворков, которые вы используете. Или общие инструменты для логирования, мониторинга, балансировки нагрузки и так далее. Можно выбрать как готовое API management решение, так и сделать своё. Толковое описание общей инфраструктуры поможет командам разработки быстрее вливаться в работу над API.
- Производительность. Рано или поздно в ночь с субботы на воскресенье кто-нибудь обязательно попытается залить в вашу систему несколько 15-гигабайтных файлов в сто потоков. Так что rate limiting, ограничения на размеры файлов и т.п. — это проблемы, которые лучше решать заранее, а не во время форс-мажорной ситуации.
- Безопасность. Кажется, что уже все привыкли использовать OAuth, если речь идёт о REST. Но и здесь стоит заранее определиться, например, с тем, собираетесь вы пользоваться scopes или нет.
- Коллекции. Вопросы, которые связаны с фильтрацией, сортировкой и разбивкой на страницы тоже лучше обсудить заранее.
- Версионирование. Здесь стоит подумать о том, что вы считаете сломом обратной совместимости. Например, может разработчик добавить новое свойство в ответ или нет. Что обещать пользователям во время выпуска новой версии. Как убирать старые методы. Об этом лучше думать в начале, чтобы у пользователей продукта сложились чёткие ожидания.
- Сообщения об ошибках. Способов их сделать очень много, лучше заранее договориться, какой именно вы выбираете для своего продукта.
- Форматы данных. Бездонная тема, которая включает в себя правильное представление валют, названий стран и т.д. Но также она касается и внутренних данных: например, если в продукте есть объект «user», то лучше, чтобы везде был один и тот же объект «user», а не пятнадцать разных.
- Документация. Помните о том, что документация — это тоже в некотором смысле публичный интерфейс. Клиентам будет намного удобнее, если внутренняя документация (OpenAPI-спецификация, описание бизнес-кейса) выглядит похоже. Так можно будет быстрее найти нужные статьи и не отвлекаться на ненужные подробности.
Как внедрить API Style Guide?
Вы сделали свой API Style Guide, и теперь осталось его внедрить. Это тоже бывает непросто. Я поделюсь своим опытом внедрения API Style Guide в одном из мест, где я работал. У компании была сложная структура: сотни инженеров, десятки распределённых команд в четырёх офисах разработки, коллеги говорили на разных языках.
Сначала нужно убедить стейкхолдеров. И тут речь часто идёт как о технических лидерах разных направлений, так и о представителях бизнеса. Все должны понимать, какие проблемы мы хотим решить и как Style Guide может в этом помочь. В моём примере все стейкхолдеры понимали, что хороший API — это важное преимущество. Многие клиенты приходили с таким запросом, да и конкуренты не дремали и активно расширяли объём возможностей, доступных через их API.
Следующая шаг — найти команду, которая это будет делать. В моём случае в компании уже была отдельная команда, которая поддерживала внешний API. Она лучше всех понимала необходимость изменений, потому что постоянно сталкивалась со сложностями в своей работе. Члены этой команды были рады поучаствовать в проекте.
Как команда внедряла API Style Guide?
- Рассказывала про инициативу на внутренних конференциях и хакатонах, чтобы все в компании понимали, о чём идет речь. Это помогало привлекать единомышленников, которые на следующих этапах очень сильно пригодились.
- Подготовила черновик Style Guide, который впоследствии согласовывала с API чемпионами (о них чуть дальше).
- Презентовала проект командам. Ребята съездили в каждый офис разработки и поговорили практически со всеми командами, объяснили смысл проекта и провели тренинги.
- Помогала с дизайном API. Многим командам было сложно с первого раза сделать всё по гайду. Здесь пригодилась помощь и дополнительные объяснения, особенно в нестандартных ситуациях.
- Проводила ревью. Важно было проверять, что все команды действуют согласно Style Guide.
Силами одной команды в большой компании очень сложно внедрить такие значительные изменения. Нужна поддержка. Здесь и подключались API чемпионы — архитекторы и техлиды каждого направления, которые помогали внедрять идею в свои команды и подразделения.
Когда происходят ключевые изменения, часто появляются недовольные. В этом случае нужен авторитет, который сможет убедить этих людей в необходимости изменений. Техлиды — самые подходящие для этого люди.
API чемпионы в отдельном Slack-канале обсуждали возникающие вопросы и предложения. Мелкие изменения вносились сразу, а более крупные требовали подробного обсуждения. В этом случае инициатор писал официальное предложение: какую проблему нужно решить, какие способы решения уже существуют, какие у них есть преимущества и недостатки. Потом мы на 1–2 дня собирались на offsite за пределами офиса, обсуждали идеи, выбирали решение и фиксировали его. После рассказывали своим командам о принятом решении: почему мы приняли именно его и что нужно делать дальше.
Также API чемпионы помогали делать ревью по своим направлениям. Ребята в их командах сначала обращались к ним, а потом финальное ревью проводила команда, которая занималась созданием Style Guide.
Через какое-то время в компании начало формироваться API community. В него вошли люди, которые прошли несколько циклов ревью, разобрались в том, что такое хороший и правильный дизайн, зачем он нужен и как его сделать. Мы создали большой чат, в котором каждый мог задать вопрос, и члены API community помогали его решить.
Нельзя внедрить подход только на уровне инжиниринга. Команды sales, support и маркетинга тоже должны понимать, какие пользовательские сценарии покрываются API, какую ценность он несет, как соотносится со стратегией компании и как правильно донести информацию о нём до клиентов.
Мы постарались всё это внедрить в онбординг большинства команд в компании, в том числе — не инженерных. Это нужно ещё и для того, чтобы все понимали когда, в каких случаях и к кому можно приходить за помощью.
Автоматизация
Последняя важная тема — это автоматизация рутинных процессов. Ревью могут служить ярким примером. В большой компании с большим количеством команд, скорее всего, нужно будет делать очень много ревью. Не хочется тратить время на базовые проблемы вроде отсутствующего описания ошибки или неправильного формата ID.
В этом могут помочь некоторые инструменты:
- Zally от Zalando проверяет, соответствует ли OpenAPI-спецификация вашему API Style Guide. Базовая конфигурация Zally проверяет на соответствие Style Guide от Zalando, но вы можете переопределять и дописывать свои правила.
- Dredd от Apiary проверяет, соответствует ли итоговая реализация REST API вашему дизайну, а именно OpenAPI, Blueprint или RAML спецификации.
Эта статья — расшифровка моего доклада с Platform Developers Conference от Miro. Видео выступления вы можете найти вот тут.
Буду рад ответить на ваши вопросы о внедрении API Style Guide. Также будет круто, если вы поделитесь похожим опытом!
Отдельное огромное спасибо Дарье Ивановой за помощь в подготовке этой статьи!