API
Author: Сергей Константинов @twirl
Date: 2021/09/23
Status: Finished
Причины прочитать: Видел рассказ автора в Яндексе, читал статьи. Уровень автора известен. Поэтому и очень интересно было, как он собрал свой опыт в одну книгу
Книга API https://github.com/twirl/The-API-Book
Вопросы до прочтения:
- Что такого особенного именно в API по сравнению с проектированием ПО?
- Как правильно выделять методы API?
- Как определять, куда какие параметры помещать?
Впечатление после прочтения
Отличная книга! Не смотря на описания API-шек псеводокодом, читается очень легко и понятно.
Понравилось про деление сущностей на уровни и запрет на смешивания уровней, это будет полезно при проектировании любой системы, а не только API к ней.
В книге отлично пройден этап от идеи до создания API через типовые ошибки. Наверняка, буду возвращаться к содержанию и не раз. Ощущаю, что грамотно подбита информация и подходы, полезные и при сборе требований, и при верхнеуровневом проектировании систем.
Основное отличие, как я понял, это то, что пользователи API - это другие разработчики. UI нет, соответственно, требования к предсказуемости поведения строже.
Понравилось про пагинацию, про ясное описание ошибок, чтобы человек понимал, что делать, про вывод неразрешимых ошибок прежде разрешимых.
Цитаты
Традиционно выношу несколько цитат:
API является как мультипликатором ваших возможностей, так и мультипликатором ваших ошибок
API должно решать задачи максимально удобно и понятно
На цитате ниже я вспомнил внедрение ограничений на платную версию карт и ограничения на построения маршрутов в навигаторе (чтобы таксисты бесплатно не юзали). Но это, все-таки другое - тут нельзя не сломать обратную совместимость. В этом же как раз и соль.
Если вы можете не ломать обратную совместимость - не ломайте её
А этот момент ниже справедлив чуть-ли не повсеместно, а не только при проектировании API
Ключевой вопрос, который вы должны задать себе 4 раза, выглядит так: “Какую проблемы мы решаем?” Задать его следует четыре раза с ударением на каждом из четырех слов
Ну а с этой цитатой сложно спорить. Тоже широкого назначения:
Если вы не можете коротко и понятно ответить на вопрос “Зачем эта сущность нужна” - значит, она не нужна
И на все вопросы (из четырех) надо смотреть под другими углом в случае АПИ:
Почему для решения этих задач требуется именно API, а не просто программное обеспечение?
Взаимодействие возможно только между сущностями соседних уровней абстракции
Важно понимать, что никакая гибкость, логичность, читабельность и расширяемость не бывает бесплатной
API должно связывать контексты
Методы, подобные только что изобретенному нами offers/search, принято называть хелперами. Цель их существования - обобщить понятные сценарии использования API и облегчить их. Под “облегчить” мы имеем в виду не только сократить многословность (“бойлерплейт”), но и помочь разработчику избежать частых проблем и ошибок
… возвращать ошибку в случае несовпадения суммы с актуальной на текущий момент. Более того, в любом API, работающем с деньгами, это нужно делать обязательно
Ниже опять цитата, которая не только к API применима:
Главное правило интерфейсов ошибок в API таково: из содержимого ошибки клиент должен в первую оченеь понять, что ему делать с этой ошибкой
А это старый-добрый закон Миллера, но теперь о количестве сущностей на одной уровне. Полезно, кстати, при проектировании систем и отображении на схемах
Человек комфортно удерживает в краткосрочной памяти 7+-2 различных объекта
Стремитесь к тому, чтобы из сигнатуры функции было абсолютно ясно, что она делает, что принимает на вход и что возвращает
К сожалению, человечество не в состоянии договориться о таких простейших вещах, как “с какого дня начинается неделя”, что уж говорить о каких-то более сложных стандартах
А это про добавление новых опций:
В таких ситуациях универсальное правило - все новые необязательные булевы флаги должны иметь значение по умолчанию false
Мой любимый термин 💘. Кстати, для реализации предлагается добавлять в вызов заголовок а-ля X-Idempotency-Token: <случайная строка="">. Сервер его запоминает и при повторном вызове не меняет результат.случайная>
Идемпотентность - повторный вызов той же операции с теми же параметрами не изменяет результат.
Повтор запроса при обрыве соединения - не исключительная ситуация, а норма жизни
Также стоит упомянуть, что добавление токенов идемпотентности к эндпоинтам, которые и так нативно идемпотентны, имеет определенный смысл, так как токен помогает различать две ситуации:
- клиент не получил ответ из-за сетевых проблем и пытается повторить запрос;
- клиент ошибся, пытаясь применить конфликтующие изменения
Если вы можете обеспечить атомарность, т.е. выполнить либо все изменения сразу, либо ни одно из них - сделайте
Любой эндпоинт, возвращающий массивы данных, должен содержать пагинацию. Никаких исключений в этом правиле быть не может
Любой эндпоинт, возвращающий изменяемые данные постранично, должен обеспечивать возможность эти данные перебрать
Подобный кейс - список страниц и выбор страниц - существует только для пользовательских интерфейсов; представить себе API, в котором действительно требуется доступ к случайным страницам данных, мы можем с очень большим трудом
Сортировка по дате модификации обычно означает, что данные могут меняться
Постройте таблицу: разрешение какой ошибки может привести к появлению другой, иначе вы можете показать одну и ту же ошибку несколько раз, а то и вовсе зациклить разрешение ошибок
если результатом операции является массив данных, то пустота этого массива - не ошибка, а штатный ответ
локацию допустимо редуцировать до кода страны
все строки должны быть в кодировке UTF-8 и никакой другой