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

Раздел I.1

This commit is contained in:
Sergey Konstantinov 2020-06-24 00:20:20 +03:00
parent 03588b02ab
commit 4ab571e807

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/).
== О структуре этой книги
## О структуре этой книги
Книга, которую вы держите в руках, состоит из трех больших разделов.
@ -18,7 +18,7 @@
Автор этой книги терпеть не может распространенный подход к написанию технических книг, когда первая мысль по сути вопроса появляется на сотой странице, а предыдущие девяносто девять страниц посвящены пространному введению и подробному описанию того, что же ждёт читателя дальше. Поэтому предисловие мы на этом заканчиваем и переходим к сути вопроса.
== API: определение
## API: определение
Прежде чем говорить о разработке API, необходимо для начала договориться о том, что же такое API. Энциклопедия скажет нам, что API — это программный интерфейс приложений. Это точное определение, но бессмысленное. Примерно как определение человека по Платону: «двуногое без перьев» — определение точное, но никоим образом не дающее нам представление о том, чем на самом деле человек примечателен. (Да и не очень-то и точное: Диоген Синопский как-то ощипал петуха и заявил, что это человек Платона; пришлось дополнить определение уточнением «с плоскими ногтями».)
@ -42,9 +42,9 @@ API — _это обязательство_. Формальное обязате
Поэтому проектирование API налагает на вас несколько большую ответственность; API выступает как мультипликатором ваших возможностей, так и мультипликатором ваших ошибок.
== I. Проектирование API
## I. Проектирование API
=== 1. Пирамида контекстов API
### 1. Пирамида контекстов API
Подход, который мы используем для проектирования, состоит из четырёх шагов:
* определение области применения;
@ -73,28 +73,68 @@ API — _это обязательство_. Формальное обязате
Итак, предположим, что мы хотим предоставить API автоматического заказа кофе в городских кофейнях. Попробуем применить к ней этот принцип.
1. Зачем кому-то может потребоваться API для приготовления кофе? В чем неудобство заказа кофе через интерфейс, человек-человек или человек-машина? Зачем нужна возможность заказа машина-машина?
* Возможно, мы хотим решить проблему выбора и знания? Чтобы человек наиболее полно знал о доступных ему здесь и сейчас опциях.
* Возможно, мы оптимизируем время ожидания? Чтобы человеку не пришлось ждать, пока его заказ готовится.
* Возможно, мы хотим минимизировать ошибки? Чтобы человек получил именно то, что хотел заказть, не потеряв информацию при разговорном общении либо при настройке незнакомого интерфейса кофе-машины.
* Возможно, мы хотим оптимизировать общую пропускную способность системы? Чтобы тысячи людей готовили свой утренний кофе, занимая все возможные кофе-машины, а не только те, которые стоят на виду.
Вопрос «зачем» — самый важный из тех вопросов, которые вы должны задавать себе. Не только глобально в отношении целей всего проекта, но и локально в отношении каждого кусочка функциональности. Если вы не можете коротко и понятно ответить на вопрос «зачем вот эта сущность нужна» — значит, она не нужна.
Здесь и далее предположим (в целях придания нашему примеру глубины и некоторой упоротости), что мы оптимизируем все три фактора в порядке убывания важности.
2. Правда ли решаемая проблема существует? Дейсвительно ли мы наблюдаем неравномерную загрузку кофейных автоматов по утрам? Правда ли люди страдают от того, что не могут найти поблизости нужный им латте с ореховым сиропом? Действительно ли людям важны те минуты, которые они теряют, стоя в очередях?
3. Действительно ли мы обладаем достаточным ресурсом, чтобы решить эту проблему? Есть ли у нас доступ к достаточному количеству кофемашин и клиентов, чтобы обеспечить работоспособность системы?
4. Наконец, правда ли мы решим проблему? Как мы поймём, что оптимизировали перечисленные факторы?
На все эти вопросы, в общем случае, простого ответа нет. В идеале ответы на эти вопросы должны даваться с цифрами в руках. Сколько конкретно времени тратится неоптимально, и какого значения мы рассчитываем добиться, располагая какой плотностью кофемашин? Заметим также, что в реальной жизни просчитать такого рода цифры можно в основном для проектов, которые пытаются влезть на уже устоявшийся рынок; если вы пытаетесь сделать что-то новое, то, вероятно, вам придётся ориентироваться в основном на свою интуицию.
==== Почему API?
Т.к. наша книга посвящена не просто разработке программного обеспечения, а разработке API, то на все эти вопросы мы должны взглянуть под другим ракурсом: а почему для решения этих задач требуется именно API, а не просто программное обеспечение? В нашем вымышленном примере мы должны спросить себя: зачем нам нужно предоставлять сервис для других разработчиков, чтобы они могли готовить кофе своим клиентам, а не сделать своё приложение для конечного потребителя?
Иными словами, должна иметься веская причина, по которой два домена разработки ПО должны быть разделены: есть оператор(ы), предоставляющий API; есть оператор(ы), предоставляющий сервисы пользователям. Их интересы в чем-то различны настолько, что объединение этих двух ролей в одном лице нежелательно. Более подробно мы изложим причины и мотивации делать именно API в разделе II.
Заметим также следующее: вы должны браться делать API тогда и только тогда, когда в ответе на второй вопрос написали «потому что в этом состоит наша экспертиза». Разрабатывая API вы занимаетесь некоторой мета-разработкой: вы разрабатывать ПО для того, чтобы другие могли разрабатывать ПО для решения задачи пользователя. Не обладая экспертизой в обоих этих доменах (API и конечные продукты) написать хорошее API сложно.
Для нашего умозрительного примера предположим, что в недалеком будущем произошло разделение рынка кофе на две группы игроков: одни предоставляют само железо, кофейные аппараты, а другие имеют доступ к потребителю — примерно как это произошло, например, с рынком авиабилетов, где есть собственно авиакомпании, осуществляющие перевозку, и сервисы планирования путешествий, где люди выбирают варианты перелётов. Мы хотим агрегировать доступ к железу, чтобы владельцы приложений могли встраивать заказ кофе.
==== Что и как
Закончив со всеми теоретическими упражнениями, мы должны перейти непосредственно к дизайну и разработки API, имея понимание по двум пунктам:
1. Что конкретно мы делаем
2. Как мы это делаем
В случае нашего кофепримера мы:
1. Предоставляем сервисам с большой пользовательской аудиторией API для того, чтобы их потребители могли максимально удобно для себя заказать кофе.
2. Для этого мы абстрагируем за нашим HTTP API доступ к «железу» и предоставим методы для выбора вида напитка и места его приготовления и для непосредственно исполнения заказа.
С этими вводными мы можем переходить непосредственно к разработке.
=== Уровни абстракции
"Разделите свой код на уровни абстракции" - пожалуй, самый общий совет для разработчиков программного обеспечения. Что под этим обычно подразумевается?
«Разделите свой код на уровни абстракции» - пожалуй, самый общий совет для разработчиков программного обеспечения. Что под этим обычно подразумевается?
Вспомним, что программный продукт - это средство связи контекстов, средство преобразования терминов и операций одной предметной области в другую. Чем дальше друг от друга эти области отстоят - тем большее число промежуточных контекстов можно ввести. Например, модель OSI, которую часто приводят как эталон разделения уровней абстракции, насчитывает семь промежуточных этапов по дороге от аппаратного обеспечения к протоколам уровня приложений.
Вспомним, что программный продукт - это средство связи контекстов, средство преобразования терминов и операций одной предметной области в другую. Чем дальше друг от друга эти области отстоят - тем большее число промежуточных контекстов нужно ввести. Если говорить о разделении уровней абстракции именно с точки зрения API, то оно очень желательно по нескольким причинам:
Если говорить о разделении уровней абстракции именно с точки зрения API, то оно очень желательно по нескольким причинам:
* Разделение проекта на несколько независимых частей; архитектура каждой из них, таким образом, становится проще, и упрощается интеграция;
* с помощью такого разделения гораздо легче добиваться кроссплатформенности путём отделения платформо-зависимой логики в отдельный уровень (или уровни) абстракции.
* разделение проекта на несколько независимых частей; архитектура каждой из них, таким образом, становится проще, и упрощается интеграция;
* с помощью такого разделения гораздо легче добиваться кроссплатформенности путём отделения платформо-зависимой логики в отдельный уровень (или уровни) абстракции.
И главное:
* Упрощается задача для ваших клиентов; правильно разделённые уровни абстракции означают, что разработчикам не придется разбираться со всей номенклатурой сущностей вашего API - им достаточно будет работать только с объектами высокого уровня, отвечающими непосредственно за решение их задач.
* упрощается задача для ваших клиентов; правильно разделённые уровни абстракции означают, что разработчикам не придется разбираться со всей номенклатурой сущностей вашего API - им достаточно будет работать только с объектами высокого уровня, отвечающими непосредственно за решение их задач.
Если мы вернёмся к нашему примеру с погодным API, то увидим, что один уровень абстракции выделился автоматически: http API. Мы можем построить прочие виды API поверх базового http. Можем ли мы выделить ещё какие-то уровни, скажем, внутри самого http API?
Вернёмся к нашему примеру с кофейнями. Какие уровни абстракции мы видим?
1. Железный. Непосредственно состояние кофе-машины и шаги приготовления кофе. Температура, давление, объём воды
2. Вкусный. У кофе есть мета-характерстики: сорт, вкус, вид напитка.
3. Торговый. Мы готовим с помощью нашего API заказ — один или несколько стаканов кофе с определенной стоимостью.
4. Геометрический. Наши кофе-машины как-то распределены в пространстве (и времени).
5. Брендовый. Кофе-машина принадлежит какой-то сети кофеен, каждая из которых обладает какой-то айдентикой и специальными возможностями.
Как мы видим даже на нашем умозрительном примере, строгая иерархия в виде уровней абстракции в реальной жизни обычно не существует. Скорее мы говорим о некоторых частично пересекающихся доменах, отвечающих за разное представление одного и того же. Какие-то из них вложены друг в друга: например, высокоуровневый термин «капучино» однозначно транслируется в набор пошаговых низкоуровневых инструкций. Другие же равноправны: например, рецепт кофе (капучино) и место его приготовления (координаты кофейни) никаких иерархий не образуют.
#### Построение иерархии абстракций