1
0
mirror of https://github.com/twirl/The-API-Book.git synced 2025-01-23 17:53:04 +02:00

First & second chapters reformulated

This commit is contained in:
Sergey Konstantinov 2020-06-16 00:34:39 +03:00
parent a9876815a9
commit 03588b02ab

View File

@ -1,10 +1,10 @@
# Сергей Константинов
# API
= Сергей Константинов
= API
[![Лицензия Creative Commons](https://i.creativecommons.org/l/by-nc/4.0/88x31.png)](http://creativecommons.org/licenses/by-nc/4.0/)
Это произведение доступно по [лицензии Creative Commons «Attribution-NonCommercial» («Атрибуция — Некоммерческое использование») 4.0 Всемирная](http://creativecommons.org/licenses/by-nc/4.0/).
## О структуре этой книги
== О структуре этой книги
Книга, которую вы держите в руках, состоит из трех больших разделов.
@ -14,11 +14,11 @@
Наконец, третий раздел будет касаться больше не-разработческих сторон жизни API - поддержки, маркетинга, работы с комьюнити.
Первые два будут интересны скорее разработчикам, третий — и разработчикам, и менеджерам. При этом я настаиваю, что как раз третий раздел — самый важный для разработчика API. Ввиду того, что API - продукт для разработчиков, перекладывать ответственность за его развитие и поддержку на не-разработчиков неправильно: никто кроме вас самих не понимает так хорошо продуктовые свойства вашего API.
Первые два будут интересны скорее разработчикам, третий — и разработчикам, и менеджерам. При этом мы настаиваем, что как раз третий раздел — самый важный для разработчика API. Ввиду того, что API - продукт для разработчиков, перекладывать ответственность за его развитие и поддержку на не-разработчиков неправильно: никто кроме вас самих не понимает так хорошо продуктовые свойства вашего API.
Автор этой книги терпеть не может распространенный подход к написанию технических книг, когда первая мысль по сути вопроса появляется на сотой странице, а предыдущие девяносто девять страниц посвящены пространному введению и подробному описанию того, что же ждёт читателя дальше. Поэтому предисловие мы на этом заканчиваем и переходим к сути вопроса.
## API: определение
== API: определение
Прежде чем говорить о разработке API, необходимо для начала договориться о том, что же такое API. Энциклопедия скажет нам, что API — это программный интерфейс приложений. Это точное определение, но бессмысленное. Примерно как определение человека по Платону: «двуногое без перьев» — определение точное, но никоим образом не дающее нам представление о том, чем на самом деле человек примечателен. (Да и не очень-то и точное: Диоген Синопский как-то ощипал петуха и заявил, что это человек Платона; пришлось дополнить определение уточнением «с плоскими ногтями».)
@ -32,61 +32,54 @@
API — _это обязательство_. Формальное обязательство связывать между собой различные программируемые контексты.
Когда меня просят привести пример хорошего API, я обычно показываю фотографию римского виадука
Когда меня просят привести пример хорошего API, я обычно показываю фотографию римского виадука:
* он связывает между собой две области
* обратная совместимость нарушена ноль раз за последние две тысячи лет.
## Проектирование API
Отличие римского виадука от хорошего API состоит лишь в том, что API предлагает _программный_ контракт. Для связывания двух областей необходимо написать некоторый _код_. Цель этой книги — помочь вам написать код, так же хорошо выполняющий свою задачу, как и римский виадук.
### Пирамида контекстов API
Виадук также хорошо иллюстрирует другую проблему разработки API: вашими пользователями являются инженеры. Вы не поставляете воду напрямую потребителю: к вашей инженерной мысли подключаются заказчики путём пристройки к ней каких-то своих инженерных конструкций. С одной стороны, вы можете обеспечить водой гораздо больше людей, нежели если бы вы сами подводили трубы к каждому крану. С другой — качество инженерных решений заказчика вы не может контролировать, и проблемы с водой, вызванные некомпетентностью подрядчика, неизбежно будут валить на вас.
Поэтому проектирование API налагает на вас несколько большую ответственность; API выступает как мультипликатором ваших возможностей, так и мультипликатором ваших ошибок.
== I. Проектирование API
=== 1. Пирамида контекстов API
Подход, который мы используем для проектирования, состоит из четырёх шагов:
* определение области применения;
* разделение уровней абстракции;
* разграничение областей ответственности;
* описание конечных интерфейсов.
* определение области применения;
* разделение уровней абстракции;
* разграничение областей ответственности;
* описание конечных интерфейсов.
Этот алгоритм строит API сверху вниз, от общих требований и сценариев использования до конкретной номенклатуры сущностей; фактически, двигаясь этим путем, вы получите на выходе готовое API — чем этот подход и ценен.
Этот алгоритм строит API сверху вниз, от общих требований и сценариев использования до конкретной номенклатуры сущностей; фактически, двигаясь этим путем, вы получите на выходе готовое API - за что мы и ценим этот подход.
Может показаться, что наиболее полезные советы и best practice приведены в последнем разделе, однако это не так; цена ошибки, допущенной на разных уровнях весьма различна. Если исправить плохое именование довольно просто, то исправить неверное понимание того, зачем вообще нужно API, практически невозможно.
Поскольку я являюсь убеждённым приверженцем практического подхода, здесь и далее я буду рассматривать проектирование API на конкретных примерах. В качестве такого примера я выбрал гипотетическое API некоего умного города. На всякий случай, предупрежу заранее, что пример является выдуманным от начала до конца.
**NB**. Здесь и далее мы будем рассматривать концепции разработки API на примере некоторого гипотетического API заказа кофе в городских кофейнях. На всякий случай сразу уточним, что пример является синтетическим; в реальной ситуации, если бы такое API пришлось проектировать, оно вероятно было бы совсем не похоже на наш выдуманный пример.
### Определение области применения
=== Определение области применения
Первый вопрос, на который мы должны ответить, принимая решение о разработке API - «зачем?». Кто и как будет пользоваться нашей программной связью контекстов?
Ключевой вопрос, который вы должны задать себе четыре раза, выглядит так: какую проблему мы решаем? Задать его следует четыре раза с ударением на каждом из четырёх слов.
Рассмотрим следующий пример. Допустим, мы умеем предсказывать погоду и располагаем возможностью предоставлять данные о погоде в машиночитаемом виде. Стоит ли нам разрабатывать API? Давайте подумаем.
1. _Какую_ проблему мы решаем? Можем ли мы чётко описать, в какой ситуации гипотетическим потребителям-разработчикам нужно наше API?
Во-первых, необходимо понять, какую такую функциональность мы можем предоставлять потребителям, что они воспользуются API, а не будут разрабатывать сами?
2. Какую _проблему_ мы решаем? А мы правда уверены, что описанная выше ситуация — проблема? Действительно ли кто-то готов платить (в прямом и переносном смысле) за то, что ситуация будет как-то автоматизирована?
По возрастанию сложности самостоятельной реализации такого функционала это будут: получение информации о текущей погоде; получение информации о прогнозе; получение информации о климате какой-то местности; получение информации о "внутреннем устройстве" предметной области - зоны высокого и низкого давления, атмосферные фронты и их движение.
3. Какую проблему _мы_ решаем? Действительно ли решение этой проблемы находится в нашей компетенции? Действительно ли мы находимся в той позиции, чтобы решить эту проблему?
Зачем такого рода функциональность может понадобиться? Вот несколько очевидных ответов:
4. Какую проблему мы _решаем_? Правда ли, что решение, которое мы предлагаем, действильно решает проблему? Не создаём ли мы на её месте другую проблему, более сложную?
* конечным пользователям - чтобы понять, нужно ли сегодня брать зонтик и куда можно съездить отдохнуть в ноябре;
* компаниям, бизнес которых зависит от погоды - например, авиаперевозчикам.
Итак, предположим, что мы хотим предоставить API автоматического заказа кофе в городских кофейнях. Попробуем применить к ней этот принцип.
Для удовлетворения первой группы потребностей потребители будут сами приходить на ресурсы, принадлежащие нашим потенциальным клиентам - популярные локальные веб-сайты (например, на городские порталы за краткосрочным прогнозом погоды или на туристические агрегаторы за информацией о климате) или разного рода приложения для "умных" устройств (телефонов, часов, планшетов, телевизоров и даже домов) или специализированные новостные ресурсы. Вторую группу потребностей будут закрывать компании, производящие программное обеспечение для диспетчерских служб - либо, возможно, проприетарные решения самих транспортных компаний.
1. Зачем кому-то может потребоваться API для приготовления кофе? В чем неудобство заказа кофе через интерфейс, человек-человек или человек-машина? Зачем нужна возможность заказа машина-машина?
* Возможно, мы оптимизируем время ожидания? Чтобы человеку не пришлось ждать, пока его заказ готовится.
* Возможно, мы хотим минимизировать ошибки? Чтобы человек получил именно то, что хотел заказть, не потеряв информацию при разговорном общении либо при настройке незнакомого интерфейса кофе-машины.
* Возможно, мы хотим оптимизировать общую пропускную способность системы? Чтобы тысячи людей готовили свой утренний кофе, занимая все возможные кофе-машины, а не только те, которые стоят на виду.
Допустим мы исследовали и рынок, и собственные технические ресурсы и пришли к выводу, что (а) мы готовы эту функциональность предоставлять, (б) пользователям она необходима и (в) мы способны извлечь для себя какую-то выгоду из предоставления такого API (подробнее обо всем этом я расскажу в третьем разделе). Тем самым мы обозначили пункт "что" - какую функциональность мы физически можем предоставить и зачем.
Следующий этап - описание пользовательских сценариев. Ответив на вопросы "что" и "зачем", нужно теперь описать ответ на вопрос "как" - как потребители API будут им пользоваться.
Очевидное решение, которое приходит в голову сразу - это выполнить наше API в виде веб-сервиса: разработчик обращается по сформированному определённым образом url и получает погодную информацию. В общем-то, всю имеющуюся у нас информацию можно через такой сервис предоставлять; он будет универсален - такое обращение можно реализовать на любой платформе, и, таким образом, оно покроет все кейсы. Разве нет?
Теперь давайте подойдём к вопросу с другой стороны. А как было бы удобно пользоваться нашим API, скажем, веб-мастеру-администратору небольшого локального форума? Скорее всего, ему требуется решение, которое не требует навыков разработки, чтобы было достаточно мышкой нащёлкать параметры информатора о прогнозе погоды. Нет, мы можем, конечно презрительно отмахнуться от таких непрофессионалов; но, тем самым, мы лишим сами себя значительной доли рынка.
Аналогично, если мы посмотрим на потребности крупных диспетчерских компаний, то мы, вероятно, выясним, что у них уже есть какое-то автоматизированной рабочее место диспетчера, и идеальным для них решением был бы набор компонентов, которые можно интегрировать в их программный комплекс. Аналогично, у новостных ресурсов также есть какое-то готовое решение для управления контентом, и они предпочтут не заказывать дорогостоящую разработку модуля визуализации погоды, а готовое решение.
Иными словами, в начале разработки API перед нами всегда стоит вопрос: насколько приближено оно должно быть к конечному пользователю? Чем более высок уровень вашего API, чем проще оно позволяет реализовать пользовательские сценарии - тем более интересно оно будет разработчикам, но тем дороже оно обойдётся вам самим. Понятно, что невозможно написать модули и компоненты для всех существующих cms и фреймворков, и вам придётся где-то остановиться - исходя из ваших представлений о массовости тех или иных кейсов. Вполне возможно, что в нашей гипотетической ситуации мы в итоге можем прийти к решению делать только http API, так как выясним, что получим от виджетов меньше дохода, чем потратим на разработку, а у каждого из крупных клиентов есть свой отдел разработки и они не доверяют в business-critical задачах разработкам сторонних компаний.
Однако, чтобы нам было, о чем говорить в дальнейших разделах, предположим, что мы решили закрывать следующие сценарии:
* общее http API для клиентов, готовых вести разработку самостоятельно;
* набор виджетов для мобильных и веб-приложений;
* набор компонентов для встраивания в АРМы диспетчерских компаний.
Перейдём теперь непосредственно к проектированию API.
### Уровни абстракции
=== Уровни абстракции
"Разделите свой код на уровни абстракции" - пожалуй, самый общий совет для разработчиков программного обеспечения. Что под этим обычно подразумевается?