Это обзор книги «API Design Patterns» Дж. Дж. Гивакса от издательства Manning.
Я уже упоминал, как стараюсь прокачиваться в теме API: читаю книги, смотрю релевантные видео на YouTube, изучаю важные RFC от IETF.
Факты
• Автор – старший инженер-программист (Principal Software Engineer) в Google
• Он же – автор сайта https://google.aip.dev/
Главы
• Введение
• Принципы проектирования
1. Именование
2. Область применения и иерархия ресурсов
3. Типы данных и умолчания
• Основы
1. Идентификация ресурсов: как выявлять ресурсы в API
2. Стандартные методы: набор стандартных методов для использования в ресурсо-ориентированных API
3. Частичные обновления и извлечения: как работать с фрагментами ресурсов
4. Собственные методы: использование собственных (нестандартных) методов в ресурсо-ориентированных API
5. Долгоиграющие операции: как обращаться с методами, которые срабатывают не мгновенно
6. Перезапускаемые задания: как выполнять в API повторяющийся собственный функционал
• Отношения на уровне ресурсов
1. Субресурсы-одиночки: изоляция фрагментов ресурсных данных
2. Перекрёстные ссылки: как в API ссылаться на другие ресурсы
3. Ассоциации в ресурсах: как при помощи метаданных организовывать отношения «многие ко многим»
4. Добавление и удаление собственных методов: как организовывать отношения «многие ко многим», не прибегая к метаданным
5. Полиморфизм: проектирование ресурсов с динамически типизируемыми атрибутами
• Коллективные операции
1. Копирование и перенос: дублирование и релокация ресурсов в API
2. Пакетные операции: расширение методов для атомарного применения групп ресурсов
3. Удаление на основе критериев: как удалять множество ресурсов на основе набора критериев, служащего фильтром
4. Анонимные операции записи: поглощение неадресуемых данных в API
5. Пагинация: потребление больших объёмов данных мелкими кусочками
6. Фильтрация: ограничение выдаваемых результатов в соответствии с фильтром, задаваемым пользователем
7. Импорт и экспорт: перемещение данных в наш API или за его пределы, напрямую работая с системой хранилища
• Безопасность и надёжность
1. Версионирование и совместимость: определение совместимости и стратегий версионирования API
2. Мягкое удаление: перенос ресурсов в «корзину» API
3. Дедупликация запросов: предотвращение дублирования работы, притом, что такое дублирование может происходить из-за сетевых перебоев при использовании API
4. Валидация запросов: как разрешить вызов методов API в «безопасном режиме»
5. Контроль версий ресурсов: отслеживание истории изменения ресурсов
6. Повторение запросов: алгоритмы для безопасной повторной отправки запросов к API
7. Аутентификация запросов: как удостовериться, что запросы аутентичны, и в них не внесено никакой посторонней информации
Главы о каждом паттерне проектирования структурно организованы одинаково:
1. Мотивация: какую задачу решает данный паттерн
2. Обзор: краткое описание паттерна
3. Внедрение: подробное объяснение паттерна. Раздел структурируется на разные подразделы
4. Компромиссы: у всех паттернов есть сильные и слабые стороны; в этом разделе описаны именно слабые
5. Упражнения: список вопросов, позволяющих убедиться, что паттерн усвоен
За и против
Начнём с хорошего:
• Как упоминалось выше, структура главы посвящена разбору конкретного паттерна проектирования и, следовательно, повторяется. Поэтому все главы легко воспринимаются, ведь понятно, чего ожидать от каждой главы.
• В принципе, я читаю технические книги перед сном, потому что днём я достаточно занят. Главы в большинстве книг длинные, поэтому, когда меня клонит ко сну, бывает, я останавливаюсь на половине главы. Возвращаясь к чтению, приходится пролистать на несколько страниц назад, чтобы освежить контекст. В книге «Паттерны проектирования API» главы отмерены идеально: ни длинные, ни короткие.
• Раздел о принципах проектирования начинается с основ. Вам не требуется быть экспертом по API, чтобы с пользой прочитать эту книгу. Я экспертом не был, но надеюсь, что теперь поднабрал опыта в этой теме.
• На первый взгляд раздел с упражнениями в конце каждой главы показался мне немного сомнительным, ведь готовых решений в этих разделах не предлагалось. Но я осознал, что такой формат включает механизм активного припоминания: вместо пассивного чтения вы, отвечая на вопросы, закрепляете в памяти изученное. В качестве дополнительного плюса, такую книгу удобно изучать в группе, сравнивать ответы и обсуждать их.
Теперь – немного критики:
• Некоторые паттерны прямо позаимствованы из документа Google’s API Improvement Proposals. Это не проблема как таковая, но при такой постановке вопроса вообще не обсуждаются возможные альтернативы. Например, в главе о собственных методах рассказано, как обрабатывать те действия, которые не соотносятся в точности с конкретным методом HTTP: пример такого действия – банковский перевод, поскольку при нём меняется два ресурса, и именно, адреса «from» и «to».
Предлагаемый Google AIP рассчитан на то, что HTTP URI будет использовать символ:, за которым пойдёт собственный метод, например, /accounts/123:transfer. Это потрясающее предложение, благодаря которому решается проблема с соотнесением. Но не предлагается никаких альтернатив, и даже не объясняется, почему должно быть так, а не иначе. Я, как инженер, вряд ли соглашусь внедрять решение, которое приводит к таким далеко идущим последствиям, если мне не покажут альтернативы и не охарактеризуют их сильные и слабые стороны.
• Наконец немаловажно, что в этой книге не упоминается никаких релевантных RFC или черновиков IETF. В главе 26 описано, как справляться с дедупликацией запросов, но, в самом деле, может потребоваться многократно выполнять одинаковый неидемпотентный запрос, не опасаясь при этом никаких побочных эффектов. Здесь предлагается хорошее решение: клиент должен использовать уникальный ключ, и, если сервер вновь получит тот же самый ключ, то такой запрос должен быть отброшен.
Именно это описано в черновике IETF: The Idempotency-Key HTTP Header Field. Однако, в книге этот черновик не упоминается, из-за чего возникает впечатление, что книга немного оторвана от экосистемы.
Ответы автора
Автор оригинального поста связывался с Дж. Дж. Гиваксом и отослал ему на просмотр черновик этой статьи. С разрешения Дж. Дж. Гивакса автор поста публикует его ответы:
• Почему в книге нет более подробного обсуждения альтернатив?
Думаю, вы правы – и, кстати, в исходной рукописи обсуждению таких альтернатив было уделено немало текста. Но в итоге я от этого материала избавился. Одна из причин – желание редактора добиться компактности глав; также сыграли роль мои внутренние споры, почему один вариант кажется мне лучше другого, и как не ограничиваться формулировкой: «а ещё есть и такой способ». Другая причина – в такой книге я хотел остаться субъективным. Если бы это был учебник для курса, в котором исследуется проектирование API, то я должен был бы взвесить все альтернативы и представить полноценную дискуссию по сильным и слабым сторонам каждого варианта. Но в большинстве случаев находилась очень хорошая опция, которую мы успели опробовать, и которой пользовались на протяжении 5+ лет (напр., в случае с собственными методами). В других случаях такого варианта действительно не находилось, и тогда в соответствующей главе активно дискутируются и рассматриваются различные альтернативы (напр., в главе о версионировании). Думаю, если бы я мог написать книгу на 600-700 страниц, то в этом отношении она бы вас более устроила.
• Почему не хватает ссылок на стандарты IETF?
С моей стороны это большой недосмотр. Есть множество RFC, и некоторые из них в книге упоминаются (напр., RFC-6902 в разделе о частичных обновлениях, т.д.). Но я действительно ошибся, не включив в книгу ещё больше материала из этого корпуса стандартов. Если будет второе издание, то этот аспект я доработаю в первую очередь.
Заключение
Поскольку в книге есть некоторые недостатки, о которых я упомянул выше, «API Design Patterns» не дотягивает до полноценного справочника. Тем не менее, это отличная книга, которую я рекомендую любому разработчику, входящему в мир API, а также более опытным коллегам, желающим дополнить свои знания на эту тему.