Паттерны проектирования API
Қосымшада ыңғайлырақҚосымшаны жүктеуге арналған QRRuStore · Samsung Galaxy Store
Huawei AppGallery · Xiaomi GetApps

автордың кітабын онлайн тегін оқу  Паттерны проектирования API

 

Джей Джей Гивакс
Паттерны проектирования API
2023

Переводчик Д. Брайт


 

Джей Джей Гивакс

Паттерны проектирования API. — СПб.: Питер, 2023.

 

ISBN 978-5-4461-1984-4

© ООО Издательство "Питер", 2023

 

Все права защищены. Никакая часть данной книги не может быть воспроизведена в какой бы то ни было форме без письменного разрешения владельцев авторских прав.

 

Посвящается Ка-эль и Луке. Вы потрясающие.

Предисловие

Все началось с электронной ударной установки. Летом 2019 года один мой друг увлек меня игрой на ней, и я погрузился в это занятие с головой. Иногда я действительно играл на барабанах, но бóльшую часть времени все же проводил за написанием кода, который позволял управлять конфигурацией установки с помощью команд MIDI SysEx.

Когда нагрянула пандемия COVID-19, у меня внезапно появились иные прио­ритеты, направленные на настройку аудиовизуальной связи в нашей местной церкви, где мы перешли в формат удаленного проведения служб и рассматривали возможности возобновления личных встреч. Для этого мне пришлось изучать протоколы VISCA, NDI и OSC (для камер и аудиомикшеров), а также осваивать программно-ориентированную интеграцию с Zoom, VLC, PowerPoint, Stream Deck и др.

Эти проекты не несут в себе больших объемов бизнес-логики. Практически весь код относится к интеграции, что одновременно и раздражает, и дает большие возможности. Раздражение вызывали протоколы, которые либо были плохо задокументированы, либо не предназначались для тех задач, которые я пытался реализовать с их помощью, либо просто не согласовывались друг с другом. Положительная сторона всего этого заключается в том, что, как только вам удастся разобраться с интеграцией, вы сможете очень легко писать полезные приложения.

Несмотря на то что моя работа в последние несколько лет заключалась в основ­ном в локальной интеграции, точно такие же раздражение и ощущение больших возможностей возникают и при работе с веб-API. Каждый опыт выбора нового веб-API представляет собой кривую, состоящую из эмоциональных реакций в виде волнения, замешательства, раздражения, принятия и достигаемого в итоге умиротворения. Как только ты досконально осваиваешь мощный API, возникает чувство, что ты являешься дирижером величественного оркестра, готового играть любую предложенную тобой музыку, — даже если ноты скрипачей согласуются лишь под конец, а для группы медных духовых без каких-либо очевидных причин приходится использовать палочку другого цвета.

Данная книга сама по себе не изменит положение дел. Это всего лишь книга. Но если после прочтения вы будете следовать указаниям, изложенным в ней, то она поможет вам обеспечить пользователям более качественный опыт. Если же эту книгу прочтет множество людей, то вместе мы сможем добиться сдвига в направлении более согласованного и менее раздражающего опыта работы с API.

Важно понять, что сама эта книга в целом гораздо более ценна, чем сумма ее фрагментов. Относительно любого из разбираемых Джей Джеем паттернов любая команда может сделать свой обдуманный выбор (хотя кто-то может упустить некоторые из указанных здесь пограничных случаев). Для конкретной ситуации этот выбор может оказаться даже более удачным, чем предложенные в книге рекомендации, ввиду ограниченных требований контекста. Такой подход позволяет получить множество локальных оптимальных решений, но дает очень фрагментированную общую картину, поскольку в этом случае даже в API одной компании потенциально применяется несколько разрозненных техник.

Помимо согласованности для любой отдельно взятой задачи, книга также предлагает единый подход, охватывающий множество сфер проектирования API. Разработчикам программных интерфейсов редко предоставляется пространство для углубленного анализа этих аспектов, и я считаю, что мне очень повезло работать с Джей Джеем и другими (в частности, с Люком Снирингером (Luke Sneeringer) над обсуждением многих тем книги. Я счастлив, что вклад, внесенный компанией Google в проектирование API, может быть весьма полезным многим разработчикам благодаря этой книге и системе AIP, расположенной по адресу https://aip.dev.

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

Используйте эту книгу как основу, чтобы построить такой API, который сможет стать фундаментом для других.

Джон Скит (Jon Skeet),Staff Developer Relations Engineer, Google

Вступление

Многие из нас изучали информатику. Мы анализировали среду выполнения и пространственную сложность алгоритмов с помощью нотации «О большое», знакомились со всевозможными алгоритмами сортировки и изучали различные способы обхода бинарных деревьев. Поэтому, окончив колледж, я планировал, что моя работа будет в первую очередь связана с математикой и точными науками. Но каким же было мое удивление, когда в действительности все оказалось совсем не так.

На деле бо́льшая часть работы была связана с проектированием, структурированием и дизайном, а не математикой и алгоритмами. Мне никогда не приходилось думать о том, какой алгоритм сортировки использовать, поскольку для этого всегда имелась библиотека (обычно что-то вроде array.sort()). Однако мне все же доводилось долго и упорно размышлять над создаваемыми классами, над функциями для них и параметрами, которые должна принимать каждая функция. Все это оказалось намного более сложным, чем я ожидал.

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

Но здесь напрашиваются вопросы: что значит «хорошо спроектированное ПО»? Что такое «хорошо спроектированный API»? Чтобы ответить на эти вопросы, довольно долго мне приходилось полагаться в основном на случайный набор ресурсов. Для одних тем я отыскивал интересные посты, которые раскрывали популярные современные альтернативы. Для других находил отдельные полезные ответы на Stack Overflow, которые подсказывали нужное направление. Однако во многих случаях было довольно мало материалов по рассматриваемой теме, и мне приходилось самостоятельно придумывать ответы, надеясь, что мои коллеги не слишком их осудят.

Спустя многие годы подобных изысканий (и таскания повсюду блокнота с надписью «Пугающие проблемы API») я наконец-то решил, что пришло время записать всю информацию, которую я собрал и использовал в работе. Поначалу все это выглядело как набор правил для Google, которые мы с Люком Снирингером систематизировали и которые в конечном итоге стали AIP.dev. Но эти правила выглядели как свод законов. В них говорилось, что нужно делать, но не пояснялось, почему нужно делать именно так. После долгого анализа и исследований, сопровождавшихся непрестанным повторением в уме этого вопроса, я готов представить вам эти правила, а также пояснить их причины.

Несомненно, было бы замечательно, если бы эта книга стала абсолютным решением для всех проблем в мире проектирования API, но, к сожалению, этого не случится. И причина тому проста: как и в архитектуре, выбор любой модели проектирования обычно опирается на личное мнение. Это означает, что одни из вас могут посчитать мои указания удачными и элегантными и будут использовать их для всех последующих проектов. Другие же могут решить, что эта книга демонстрирует отвратительные и чрезмерно ограниченные модели дизайна, и в связи с этим, наоборот, воспринять их в качестве примера того, как не нужно проектировать API. Поскольку я не могу угодить всем, моей единственной целью было предоставить набор проверенных в деле рекомендаций, подкрепив их логическими обоснованиями, объясняющими, почему они выглядят именно так.

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

Благодарности

Как и бо́льшая часть моей работы, эта книга стала результатом усилий множества людей. В первую очередь хочу поблагодарить свою жену, Ка-эль, за то, что выслушивала мои разглагольствования и жалобы в трудный период окончательной доработки рукописи. Велика вероятность, что не будь постоянной поддержки Ка-эль, я мог бы забросить работу над книгой. Кроме того, аналогичную роль сыграли и многие другие люди, включая Кристен Раньери, Бекки Сусел, Джанетт Кларк, Норриса Кларка, Тадж Кларка, Шерин Чан, Асфию Фазал и Адаму Диалло (Kristen Ranieri, Becky Susel, Janette Clarke, Norris Clarke, Tahj Clarke, Sheryn Chan, Asfia Fazal, Adama Diallo), которым я также очень благодарен.

Команда приверженцев API сыграла важную роль в рецензировании и обсуждении тем книги, а также предоставила ценные рекомендации. В частности, хочу сказать спасибо Эрику Брюэру, Хонгу Чжану, Люку Снирингеру, Джону Скиту, Альфреду Фуллеру, Энджи Лин, Тибо Хоттелье, Гаррету Джонсу, Тиму Берксу, Маку Ахмаду, Карлосу О’Райану, Маршу Гардинеру, Майку Кистлеру, Эрику Уилеру, Максу Россу, Марку Якобсу, Джейсон Вудард, Майклу Рубину, Майло Мартину, Брэду Майерсу, Сэму Маквити, Робу Клевенджеру, Майку Шварцу, Льюису Дейли, Майклу Ричардсу и Брайану Гранту (Eric Brewer, Hong Zhang, Luke Sneeringer, Jon Skeet, Alfred Fuller, Angie Lin, Thibaud Hottelier, Garrett Jones, Tim Burks, Mak Ahmad, Carlos O’Ryan, Marsh Gardiner, Mike Kistler, Eric Wheeler, Max Ross, Marc Jacobs, Jason Woodard, Michael Rubin, Milo Martin, Brad Meyers, Sam McVeety, Rob Clevenger, Mike Schwartz, Lewis Daly, Michael Richards, Brian Grant) за всю их помощь в течение нескольких лет.

Кроме того, многие участвовали в создании книги косвенно, выполняя возложенную на них часть работы, за что я выражаю признательность Рою Филдингу, Банде четырех (Эрих Гамма, Ричард Хелм, Ральф Джонсон и Джон Влиссидес), Санджаю Гемаватту, Урсу Хельцле, Эндрю Файксу, Шону Куинлану и Ларри Гринфилду (Roy Fielding, Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, Sanjay Ghemawatt, Urs Hoelzle, Andrew Fikes, Sean Quinlan, and Larry Greenfield). Хочу также поблагодарить Стю Фельдмана, Ари Балога, Рича Санци, Йорга Хайлига, Эяль Манора, Юрия Израилевского, Уолта Драммонда, Цезаря Сенгупту и Патрика Тео (Stu Feldman, Ari Balogh, Rich Sanzi, Joerg Heilig, Eyal Manor, Yury Izrailevsky, Walt Drummond, Caesar Sengupta, Patrick Teo) за их поддержку и советы при изучении рабочих тем в Google.

Отдельная благодарность Дэйву Наглу (Dave Nagle) за поддержку в области рекламы, облачных сервисов, API и прочих аспектов, а также за то, что помог мне выйти из зоны комфорта. Выражаю признательность и Марку Чедвику (Mark Chadwick), который более десяти лет назад помог мне преодолеть синдром самозванца в проектировании API. Конструктивная обратная связь Марка и его добрые слова во многом подтолкнули меня погрузиться в изучение этой интересной области компьютерной науки. Отдельное спасибо говорю Марку Хаммонду (Mark Hammond), который научил меня ставить все под сомнение.

Данный проект оказался бы невозможным без команды Manning, в частности Майка Стивенса (Mike Stephens) и Маржаны Байс (Marjan Bace), которые одобрили саму идею книги, а также Кристины Тейлор (Christina Taylor), посвятившей себя моему очередному долгосрочному проекту. Выражаю признательность также Элу Кринкеру (Al Krinker) за детальный обзор всех глав, редактору проекта Дейрдре Хиаму (Deirdre Hiam), литературному редактору Мишель Митчелл (Michele Mitchell), корректору Кери Хэйлз (Keri Hales) и техническому редактору Ивану Мартиновичу (Ivan Martinovic). Спасибо всем сотрудникам Manning, кто помог воплотить этот проект в жизнь.

Благодарю всех рецензентов: Акшата Пола, Энтони Крэмпа, Брайана Дейли, Криса Хенегана, Даниэль Бретой, Дэвида Дж. Бисака, Дениза Вехби, Херардо Лекароса, Жана Лазару, Джона К. Гунвальдсона, Хорхе Эсекьель Бо, Йорта Роденбурга, Люка Купку, Марка Ненадова, Рахул Райа, Ричарда Янга, Роджера Доуэлла, Рубена Вандегинсте, Сатей Кумар Саху, Ставена Смита, Юла Уильямса, Юрия Бодарева и Зохеба Айнапора (Akshat Paul, Anthony Cramp, Brian Daley, Chris Heneghan, Daniel Bretoi, David J. Biesack, Deniz Vehbi, Gerardo Lecaros, Jean Lazarou, John C. Gunvaldson, Jorge Ezequiel Bo, Jort Rodenburg, Luke Kupka, Mark Nenadov, Rahul Rai, Richard Young, Roger Dowell, Ruben Vandeginste, Satej Kumar Sahu, Steven Smith, Yul Williams, Yurii Bodarev, Zoheb Ainapore). Ваши рекомендации помогли улучшить эту книгу.

О книге

Я написал эту книгу, стремясь предложить разработчикам безопасные, гибкие и многократно используемые паттерны создания API. Она начинается с рассмотрения ряда общих принципов проектирования, и далее описывается набор паттернов проектирования, которые могут предоставить простые решения для типичных сценариев создания API.

Для кого эта книга

Эта книга для всех, кто уже разрабатывает веб-API или планирует заняться его разработкой, в особенности собираясь сделать его публичным. Будет хорошо, если читатели будут знать о некоторых форматах сериализации (например, JSON, Google Protocol Buffers или Apache Thrift) и распространенных парадигмах хранения данных (например, схемах реляционных баз данных), но эти знания вовсе не обязательны. Будет кстати и наличие опыта работы с HTTP и его методами (например, GET и POST), поскольку именно этот протокол был выбран для использования в примерах книги. Если в процессе разработки API вы столкнетесь со сложностями и подумаете: «С этим уже точно кто-то разобрался», — то эта книга для вас.

Структура издания

Книга разделена на шесть частей. Первые две посвящены более общим темам разработки API, а последующие четыре — самим паттернам проектирования. В части I закладывается фундамент для всего последующего материала, предоставляется ряд определений и оценочных схем для веб-API и паттернов проектирования, которые мы будем применять к этим веб-API в дальнейшем.

• Глава 1 начинается с точного определения понятия API и разъяснения важности этого программного продукта. Здесь же предоставляется своеобразная схема для оценки качества API.

• В главе 2 продолжает рассматриваться тема главы 1, изучаются способы применения паттернов проектирования к API и дается объяснение того, в чем заключается их польза для разработчиков. Здесь также разбирается анатомия паттерна проектирования API и приводится краткий пример того, как использование одного из таких паттернов может помочь получить более качественный API.

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

• В главе 3 разбираются все компоненты, которым может потребоваться присвоение имен в API, и поясняется, на что необходимо обращать внимание при выборе этих имен. Здесь также демонстрируется, почему именование является критически важным, хотя и кажется чем-то незначительным.

• В главе 4 описываются более крупные API, где могут использоваться несколько взаимосвязанных ресурсов. Рассматривается ряд вопросов, актуальных при выборе ресурсов и их связей. Завершается глава разбором нескольких примеров того, чего следует избегать.

• В главе 5 описано, как правильно использовать в API различные типы данных и предустановленные для них значения. В ней охвачены наиболее распространенные типы, такие как строки и числа, а также более сложные наподобие карт и списков.

В части III мы переходим к началу каталога паттернов проектирования и первыми рассмотрим фундаментальные паттерны, которые должны применяться практически ко всем API.

• В главе 6 представлен подробный разбор способов идентификации ресурсов пользователями API, с погружением в детали идентификаторов, такие как tombstoning (отметка об удалении), набор символов и кодировки, а также использование контрольных сумм для различения между отсутствующими и недействительными ID.

• В главе 7 подробно описывается, как должны работать различные стандартные методы веб-API (Get, List, Create, Update и Delete). В ней также объясняется, почему важно, чтобы каждый стандартный метод вел себя совершенно одинаково во всех ресурсах, а не менялся в зависимости от особенностей каждого из них.

• В главе 8 особое внимание уделяется двум стандартным методам (Get и Update) и показывается, как пользователи могут взаимодействовать не со всем ресурсом сразу, а с отдельными его частями. Кроме того, в ней разъясняется, почему это необходимо и полезно (и для пользователей, и для API), а также то, как сделать поддержку этой функциональности максимально ненавязчивой.

• В главе 9 мы выйдем за рамки стандартных методов и откроем путь к реализации в API любых нужных нам действий с помощью пользовательских методов. Особое внимание уделяется объяснению того, когда такие методы имеют смысл (и когда нет), а также тому, как принимать это решение в собственных API.

• В главе 10 рассматривается уникальный сценарий, в котором методы API могут не быть мгновенными, и поясняется, как поддерживать это удобным для пользователей образом с помощью длительных операций (longrunning operations, LRO). В ней разбираются принцип работы LRO и все методы, которые могут поддерживаться этими операциями, включая паузу, возобновление и отмену длительно выполняющейся задачи.

• В главе 11 читатель познакомится с принципом выполнения повторяющейся работы, в некотором роде напоминающей планирование задач для веб-API. Здесь объясняется, как использовать ресурсы Execution и выполнять их либо по расписанию, либо по требованию.

Часть IV посвящена ресурсам и принципам их взаимосвязи и в некотором роде содержит более обширный разбор материала главы 4.

• В главе 12 показывается, как небольшие изолированные части связанных данных можно отделять в подресурсы-одиночки. В ней детально рассматриваются обстоятельства, при которых это оказывается хорошей идеей (или нет).

• В главе 13 описывается, как ресурсы в веб-API должны хранить ссылки на другие ресурсы с помощью либо ссылочных указателей, либо встроенных значений. В ней также объясняется, как обрабатывать пограничные случаи, такие как каскадирование удалений или обновлений по мере изменения ссылочных данных во времени.

• В главе 14 более широко раскрывается тема связей между ресурсами по типу «один к одному» и объясняется, как использовать ассоциирующие ресурсы для представления связей по схеме «многие ко многим». В ней также описываются способы хранения метаданных об этих связях.

• В главе 15 рассматривается использование сокращенных методов Add и Remove в качестве альтернативы ассоциирующим ресурсам при обработке связей формата «многие ко многим». Помимо этого, в ней разбираются некоторые компромиссы при использовании этих методов и поясняется, почему они не всегда оказываются подходящими.

• Глава 16 посвящена изучению сложного принципа полиморфизма, при котором переменные могут получать целый спектр различных типов. В ней описывается обработка полиморфных полей в ресурсах API, а также объясняется, почему полиморфных методов стоит избегать.

В части V мы выйдем за границы взаимодействия с одним ресурсом API за раз и начнем рассматривать паттерны проектирования, предназначенные для взаимодействия с целыми коллекциями ресурсов.

• В главе 17 объясняется, как ресурсы можно копировать или перемещать в API. В ней разбираются тонкие моменты, такие как обработка внешних данных, метаданные, наследуемые от другого родителя, и то, как правильно рассматривать дочерние ресурсы.

• В главе 18 рассказывается о способах адаптирования стандартных методов (Get, Create, Update и Delete) под одновременное оперирование не с одним ресурсом, а с их коллекцией. В ней также разбирается ряд сложных тем, например, как должны возвращаться результаты и как обрабатывать частичные сбои.

• В главе 19 более широко раскрывается идея пакетного метода удаления, приведенная в главе 17, с примером того, как можно удалять ресурсы, соответствующие заданному фильтру, а не конкретному идентификатору. Помимо этого, в ней рассматриваются способы налаживания согласованности и даются практические рекомендации, помогающие избежать случайного уничтожения данных.

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

• В главе 21 объясняется, как обрабатывать просмотр больших наборов данных с помощью разбивки на страницы, используя для перебора этих данных непрозрачные токены. В ней также показывается, как применять пагинацию внутри одиночных крупных ресурсов.

• В главе 22 рассказывается, как применять критерий фильтрации к листингам ресурсов, а также демонстрируется лучший способ представления этих фильтров в API. Все это применяется непосредственно к темам, разобранным в главе 19.

• В главе 23 рассматривается обработка импорта и экспорта ресурсов в API. Кроме того, здесь подробно описаны различия между операциями импорта и экспорта в сравнении с резервным копированием и восстановлением.

В части VI мы сосредоточимся на несколько менее интересной теме реализации безопасности в API. Узнаем, как обеспечивать их защиту от злоумышленников и обезопасить предоставляемые в API методы от собственных ошибок пользователей.

• В главе 24 исследуется тема версионирования и объясняется, что означает совместимость разных версий. Идея совместимости рассматривается через призму разнообразия, и поясняется важность определения политики совместимости, согласующейся по всему API.

• В главе 25 начинается работа по защите пользователей от собственных ошибок, предоставляется паттерн (мягкое удаление), позволяющий удалять ресурсы из представления, не удаляя их полностью из системы.

• В главе 26 описывается защита системы от повторяющихся действий с помощью идентификаторов запросов. В ней разбираются тонкости использования ID запросов, а также алгоритм обеспечения правильной обработки этих ID в крупномасштабных системах.

• В главе 27 рассказывается о проверочных запросах, которые позволяют пользователям получить превью действия в API без фактического выполнения внутренней операции. В ней также демонстрируется обработка более продвинутых моментов, таких как побочные эффекты, возникающие во время запросов реального времени и проверочных запросов.

• В главе 28 вводится понятие ревизии ресурсов, используемой для отслеживания изменений во времени. Помимо этого, в ней разбираются связанные базовые операции, такие как откат к предыдущим ревизиям, и более продвинутые темы наподобие применения ревизий к дочерним ресурсам в иерархии.

• В главе 29 представляется паттерн для информирования пользователей о том, когда запросы API нужно повторить. Кроме того, здесь приводятся руководства по различным кодам HTTP-ответов и инструкции, поясняющие, когда их можно безопасно повторять.

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

О коде

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

Во многих случаях начальный исходный код подвергался переформатированию. То есть мы добавляли разрывы строк и перерабатывали отступы, чтобы оптимально задействовать все доступное пространство страниц книги. Кроме того, во многих случаях, когда код листинга описывался в тексте, комментарии из этого листинга удалялись. Многие листинги сопровождаются аннотациями, которые поясняют наиболее важные детали.

После долгих обсуждений с первыми читателями и командой рецензентов я по ряду причин решил использовать в качестве стандартного языка TypeScript (TS). Он будет понятен как тем, кто знаком с динамическими языками (такими как JavaScript или Python), так и тем, кто работает со статическими (например, Java или C++). Это может кому-то не понравиться, и не все читатели смогут с ходу начать писать собственный TS-код, однако фрагменты, приводимые на этом языке, можно рассматривать просто как псевдокод, который должен быть понятен большинству разработчиков.

Когда дело доходит до определения API с помощью TS, нужно реализовывать два вида компонентов: ресурсы и методы. Что касается первых, то примитивы TS (например, интерфейсы) оказываются довольно выразительными при определении схем ресурсов API, позволяя почти всегда вписывать определения API буквально в несколько строк. В связи с этим все ресурсы API определяются в виде интерфейсов TS, что дает дополнительный бонус в виде более наглядных представлений JSON.

Что же касается методов API, то с ними все немного сложнее. В этом случае я предпочел задействовать для представления целого API абстрактные классы TS, следуя соглашению, обычно используемому при реализации RPC с помощью Google Protocol Buffers. Это дает возможность определять только методы API, не беспокоясь о внутренних реализациях.

При рассмотрении входов и выходов методов API я решил снова ориентироваться на Protocol Buffers, размышляя в контексте интерфейсов запросов и ответов. Это означает, что в большинстве случаев будут встречаться интерфейсы, представляющие эти входы и выходы и названные по имени метода API с добавлением суффикса -Request или -Response (например, CreateChatRoomRequest для метода CreateChatRooom).

Наконец, поскольку эта книга во многом опирается на принципы RESTful, необходимо было обеспечить способ отображения этих RPC в URL (и HTTP-метод). Для этого я предпочел использовать декораторы TS в качестве аннотаций различных методов API, выделив по одному для каждого отдельного HTTP-метода (например, @get, @post, @delete). Чтобы указать путь URL, в который должен отображаться метод API, каждый декоратор принимает шаблонную строку, которая также поддерживает подстановку переменных в интерфейсе запроса. К примеру, @get("/{id=chatRooms/*}") будет заполнять поле ID запроса. В этом случае звездочка обозначает заполнитель (placeholder) для любого значения, за исключением символа слеша.

Как бы ни было замечательно иметь возможность опираться на спецификации OpenAPI для всех этих паттернов проектирования, есть ряд проблем, которые могут создать сложности для читателей. Во-первых, спецификации OpenAPI предназначены для использования в первую очередь компьютерами (например, генераторами кода, рендерами документации и т.д.). А поскольку цель этой книги — донести сложные темы проектирования API до других разработчиков API, то OpenAPI оказывается не лучшим способом из доступных.

Во-вторых, несмотря на все волшебство проекта OpenAPI, его использование будет довольно громоздким независимо от того, в каком формате мы станем представлять API: в YAML или JSON. К сожалению, хоть эти сложные темы и можно выразить с помощью OpenAPI, такой подход окажется не самым лаконичным решением и приведет к большому количеству лишнего содержимого, не имеющего особой ценности.

Ну и последнее: при оценке использования OpenAPI, Protocol Buffers и TypeScript первые читатели и рецензенты дали четкую обратную связь, что вариант с TS для данного конкретного случая подходит лучше всего. Имейте в виду, что я вовсе не навязываю никому определять API с помощью TS. Просто для данного проекта этот язык подошел наилучшим образом.

Онлайн-ресурсы

Дополнительную информацию по проектированию API можно найти на ресурсе https://aip.dev, где детально разбирается множество сопредельных тем.

Об авторе

Джей Джей Гивакс трудится инженером ПО в Google, специализируясь на платежных системах, облачной инфраструктуре и проектировании API. Он также является автором книги Google Cloud Platform in Action и сооснователем AIP.dev, запущенного в Google общеотраслевого ресурса, который посвящен сотрудничеству в сфере разработки стандартов построения API. Живет в Сингапуре со своей женой Ка-эль и сыном Лукой.

Иллюстрация на обложке

На обложке представлена иллюстрация под названием Marchand d’Estampes à Vienne, или «Торговец полиграфией в Вене». Она взята из коллекции костюмов различных стран, составленной Жаком Грассе де Сен-Совером (1757–1810 годы) и опубликованной им в 1797 году под названием Costumes de Différents Pays. Каждая иллюстрация была старательно отрисована и раскрашена от руки. Богатое разнообразие коллекции Грассе де Сен-Совера напоминает нам, насколько культурно разнообразными были города и регионы планеты буквально 200 лет назад. Будучи изолированными друг от друга, люди говорили на разных диалектах и языках. В поселениях по одеянию человека можно было легко определить, где он живет, чем занимается и какое положение в обществе занимает.

С тех пор манеры одеваться очень изменились. Теперь сложно различить даже жителей разных континентов, не говоря уже о гражданах разных городов, регионов и стран. Возможно, мы променяли культурное разнообразие на более разнообразную личную жизнь — и уж точно на более разнообразную и динамичную технологическую.

Во времена, когда сложно отличить одну компьютерную книгу от другой, издательство Manning чествует изобретательность и новаторство компьютерного бизнеса с помощью обложек, отражающих богатое разнообразие региональной жизни двухсотлетней давности, о котором нам напоминают картины Грассе де Сен-Совера.