Хабрахабр

Особенности разработки API: какой API является хорошим?

Наверное, абсолютно все читатели используют API, работая с фрэймворками, библиотеками, виджетами, как некий язык общения между сущностью и основным приложением. И вы наверняка замечали, что некоторыми API удобнее пользоваться, а в некоторых есть явные проблемы. Всеволод Шмыров (@vsesh) в своем докладе на Frontend Conf, расшифровку которого вы найдете под катом, постарался ответить на вопрос, какой API является хорошим.

Все то, о чем пойдет речь, относится именно к публичному АPI. Рассказ опирается на опыт разработки АPI Яндекс.Карт, и хотя это и JavaScript-библиотека, многие принципы и особенности его разработки применимы и к другим типам АPI, к примеру, к серверным API и Standalone библиотекам. Если к API вашей библиотеки обращаются только ваши коллеги, которым вы можете легко рассказать, что где-то что-то надо поменять, то вы, скорее всего, не столкнетесь с теми проблемами, с которыми сталкиваются разработчики публичного АPI.

image

Надеемся, после прочтения вы взвесите все «за» и «против» и сами поймете, нужен ли он вам. Однако, в докладе не будет ответа на вопрос, нужен ли вам свой API. Всеволод просто расскажет, с какими сложностями приходится сталкиваться разработчикам API, какие проблемы решать и что еще делать, а именно про эти четыре важных пункта:

О спикере: Всеволод Шмыров — старший разработчик интерфейсов в компании Яндекс, непосредственно участвовал в разработке API Яндекс.Карты и конструкторе карт Яндекс.

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

Будь проще

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

Там был метод getFriends. Несколько лет назад я столкнулся с API одной социальной сети.

getFriends( ) => [ ]

На самом деле, несмотря на то что на слайде у меня JS-псевдокод, это была серверный endpoint, которому ты послал запрос getFriends с параметром и получал список друзей. Вроде все логично, запрашиваешь друзей, получаешь друзей. Мой код, который работал с этим API выглядел бы как-то так:

var friends = getFriends( );

Но разработчики почему-то решили, что этого недостаточно. Они решили сделать следующее, если у тебя нету друзей, то вместо пустого списка ты получаешь Null.

Ладно, мой код тогда стал выглядеть соответствующе:

var friends = getFriends ( );
If (friends) { // …
} else { // …
}

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

Мой код стал уже выглядеть так: Становится понятно, что API непростой, нелогичный.

var friends = getFriends( );
If (isUser(friends))
elseif (friends) { /*…*/}
else { /*…*/}

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

Вы используете какой-то метод на API и дальше работаете с данными, и вам не нужно писать страшные условия. Хороший API — это тот, который не заставляет писать лишнее.

Давайте подытожим, интерфейс должен быть:

  • Простым и логичным
  • Консистентным
  • Но не в ущерб возможностям

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

iCanShowYou({x: 1, y: 1});
NoUCant([1, 2]);
ButIMust(Point);

К примеру, в API Карт часто используется тип данных координаты, они у нас представлены в виде массива — широта, долгота. И они так описаны везде, то есть у нас нет методов, которые принимали бы объект XY, объекты Long Lat или вообще два объектами. Координаты везде представлены именно массивом.

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

someAwesomeMethod( elem, /* required */ index, /* = "key" */ startValue, /* = 0 */ endValue /* = 1 */
);

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

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

new ymaps.GeoObject( geometry, /* {Object} */ properties, /* {Object} */ options, /* {Object} */
);

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

new ymaps.GeoObject(geometry), // Любыегеометрии
new ymaps.Placemark(coord), // Только “Point”

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

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

geolocation.get() .then(function (result) { // success }, function (error) { // error });

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

Работает это следующим образом, разработчик пишет в коде geolocation.get, этот код исполняется, а в браузере вылезает такое окошечко.

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

Рукописи не горят

Этот раздел посвящен обратной совместимости. У вас наверняка был такой случай.

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

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

Обратная совместимость

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

Вообще все логично, сделал, работает — не трогай!

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

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

Допустим у вас есть один модуль, который возможно использовать только одним способом. Чем больше степени свободы разработчика, тем больше требуется ресурсов на поддержку. Потом у вас появилось сто модулей, и вместе с ними огромное количество комбинаций и непредвиденных ситуаций, которые вы даже не можете предположить. Потом у вас появился второй модуль, теперь можно использовать первый модуль, можно второй, можно использовать оба модуля вместе. Таким образом повышается риск возникновения какой-то непредвиденной ошибки.

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

Если вы все-таки решили опубликовать некоторую сущность, нужно думать о том, что интерфейс будет расширяемым.

У нас когда-то был метод, впринципе он и сейчас есть, balloon.setPosition. Давайте рассмотрим пример. Туда можно было передать две координаты, широта, долгота, которые ниже обозначены x и y.

balloon.setPosition( x, y// обязательные аргументы
)

Как я говорил ранее у нас все координаты записывается не двумя аргументами, а одним, так как они оба являются обязательным аргументом. Поэтому лучше их скрепить в один аргумент [x, y] и пометить его как обязательный. Потом мы подумали, что хорошо бы разрешить передавать кроме широты и долготы еще и проекцию, у нас есть проекция по умолчанию, но можно задать какую-то собственную проекцию. Мы могли бы добавить опцию Projection, но потом нам наверняка потребовалось бы добавить какие-то еще опции. Тогда мы решили, что мы сразу сделаем options, внутри укажем проекцию и в будущем сможем добавлять любые другие ключи. То есть мы сделали интерфейс расширяемым, и он никак не блокирует будущую разработку.

Все то, о чем я сейчас говорил, нужно для того, чтобы понять, не станет ли ваш новый интерфейс «блокером» в будущем?

Когда-то давным-давно мы решили опубликовать метод getLayout в сущности overlay. Давайте я снова сразу перейду к примеру. Мы могли бы опубликовать интерфейс так: На тот момент у нас был один единственный Layout, который был реализаций класса символа HTMLLayout.

overlay.getLayout() // HTMLLayout

Тогда в будущем мы бы не смогли создавать Layout кроме как html. Поэтому мы сделали метод, который возвращает интерфейс ILayout, который будет возвращать HTMLLayout.

overlay.getLayout() // ILayout // HTMLLayout, CanvasLayout…

А разработчик, который использует API, уже в зависимости от своих нужд может поставить переключиться, например, на CanvasLayout.

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

Исправление ошибок

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

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

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

presets.get(‘islands#greyicon’);
presets.get(‘islands#grayicon’);

То же самое мы делали с методами, когда находили опечатки.

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

Разработчики, которые используют API, использовали следующим образом: по ссылке Где-то примерно два года назад, мы переписывали бэкенд API с одной серверной технологии на другую.

https://api-maps.yandex.ru/2.1/?lang=ru_RU&mode=debug

подключали скрипт на страницы и все прекрасно работало.

Дело было в амперсанде — часть пользователей копировала ссылку со спец символом «&», который в html трактуется как амперсанд и хорошо работает. Мы переехали на Node.js и вдруг пошли жалобы от пользователей. При это происходила следующая ошибка, вместо параметра «mode» приходил «amp;mode». Но часть пользователей копировала эту ссылку как есть, то есть такой запрос и отправлялся не сервер. То есть там приходил lang, mode и куча пустых amp. Старый бэкенд это обрабатывал, потому что считал символ «;» разделителем get параметров наравне с символом амперсанда.

Поэтому мы просто добавили middleware, который удаляет amp из get параметров и только лишь после этого их обрабатывает. Мы посмотрели сколько пользователей делали такие запросы к нам и поняли, что мы не можем всем объяснить то, что так делать неправильно. Да, это глупо, но приходится и с таким жить.

Мажорные релизы

Но не все так безнадежно, ошибка в обратной совместимости не будет преследовать вас до конца жизни. Только до конца, до следующей мажорной версии.

1, чтобы обновить список браузеров, которые мы поддерживаем. Где-то года три назад мы решили выпустить мажорную версию API 2. 0 она была очень старая, она поддерживала даже IE 6 — понимаете, какая это боль. Версия API 2. 1 мы все еще поддерживаем IЕ 8, потому что три года назад это был достаточно актуальный браузер (сейчас IE 8 уже находится в слабой поддержке).
Но, к сожалению, в 2.

Если у вас на предприятии используется IЕ, обновляйтесь, хватит терпеть. Если честно, я вам скажу по секрету, только между нами, в будние дни доля IЕ 8 где-то порядка 4%, а на выходных она проседает меньше 1%.

Так вот, обновление списка браузеров — это тоже слом обратной совместимости, в старых браузерах API работать не будет, поэтому мы и назвали эту версию 2.1. Заодно решили пуститься во все тяжкие и сломать обратную совместимость даже там, где это не было необходимо. Мы почистили код от всех тех алиасов и от костылей, которые нам было необходимо поддерживать из-за обратной совместимости, удалили некоторые старые полифилы для IЕ 6.

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

«Особый режим» работы

В JavaScript есть строгий режим работы ‘use strict’, когда вы пишите тот же самый код, он визуально выглядит также, но трактуется немножко по-другому. У нас есть похожий режим работы, правда он служит совершенно для другой цели.

https://api-maps.yandex.ru/2.1/?lang=ru_RU&coordorder=longlat

У нас есть get параметр coordorder, которым можно управлять порядком координат в массиве, про который я говорил ранее. По умолчанию у нас широта, долгота (longlat). Можно передать долготу, широту (latlong). В разных гео-системах используется разный порядок координат. Соответственно, при указании get параметров получается другой режим работы.

Весь API работает немножко по-другому, и при расчетах это нужно учитывать.

Обратная совместимость влияет не только на код, как можно было бы подумать. Что еще можно сказать про обратную совместимость?

Не так давно мы выпустили новую минорную версию API, в котором обновили элементы управления карты. Если вы разрабатываете визуально API, то есть API, который что-то показывает, то у вас есть обратная совместимость и на визуальную составляющую. Почему мы так поступили? Они стали более светлыми, более плоскими, как сейчас модно, но они практически не изменили свой размер. Мы могли в теории сделать большущие кнопки, сделать их полукруглыми, изменить иконки или вообще убрать иконки, но это нарушало бы обратную совместимость.

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

В нашем случае, что-то в браузере ломается — что-то ломается в API. Еще хочу заметить, что очень часто обратная совместимость ломается каскадно.

На прокрутку колесика мышки стал приходить не плюс, а минус. У нас был такой немножко грустный забавный случай, когда в одном браузере, у которого уже примерно 80% доли пользователей, в событии MouseEventвдруг поменялся знак. Нам за два дня, пока браузер это не починил, нам пришло порядка трех тысяч писем в день. Естественно, когда человек пытался приблизить карту колесиком мышки, она начинала от него отдаляться. Чтобы вы понимали, обычно даже в самые напряженные дни приходит около десяти писем, то есть людям действительно доставило неудобство то, что карта вдруг резко поменяла свое поведение.

Свой среди чужих

Этот раздел посвящен JavaScript API, но тем не менее он тоже достаточно интересен. API работает в чужом контексте, что это значит? Допустим есть первый сайт, который использует API карт, и там все хорошо работает. Есть второй сайт, который использует API, но еще он использует и библиотеку jQuery — тоже все работает нормально. А есть третий сайт, который использует API карт и некоторые evil.js, который зачем-то переопределяет базовые методы.

Видимо разработчик этого метода решил поддерживать IЕ 6, не проверил существование настоящего indexOf и написал такой: В примере ниже ошибка в том, что indexOf не возвращает минус один.

Array.prototype.indexOf = function (item) { for (var i = 0; i < this.length; i++) if (item ==this [i]) return i;
};

API естественно в этом случае ломается. Или, к примеру, мы сталкивались с таким кодом:

* {
transition: 2s all ease;
}

Кто-то зачем-то написал такой CSS селектор, который оставляет абсолютно все на странице быть анимированным.

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

Обычно у нас это происходит следующим образом: в поддержку приходит жалоба пользователя то, что что-то не работает, с приложенной ссылкой; мы ее открываем, смотрим что в API что-то сломалось; начинаем смотреть CSS, JS и это не всегда бывает удобно. Но я хочу подчеркнуть то, что на это тоже нужно тратить ресурсы. На это тоже придется тратить время, если вы разрабатываете именно JS-библиотеку или API, который внедряется в чужой контекст.

Вы не знаете свой продукт

API, как я говорил раньше, это продукт, и вы не знаете, как вашим продуктом пользуются. Когда-то в версии 2.0 мы столкнулись с тем, что очень много людей создавало такие маленькие карты, а мы про этот кейс просто не подумали.

А мы просто, когда создавали 2. Карта малюсенькая, где-то 150*150 пикселей, и на левой карте все управляющие элементы друг на друга наехали. Но когда мы это увидели, в 2. 0 об этом не подумали, ну кому нужна такая малюсенькая карта. Мы сделали адаптивные элементы — это очень простое решение, чем шире карта, тем шире элементы. 1 мы проработали над этим, и на правом рисунке уже все помещается.

Но это стало возможно только лишь после навешивания метрик на собственные методы API. Соответственно, на больших картах поиск полностью отображается, а на маленьких кнопочка, по клику на которую сверху выползает поиск.

Метрики

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

Мы сталкивались с тем, что люди создавали, как маленькие карты, так и очень большие — бывают значения порядка 5000*4000. В нашем случае важным параметром был размер карты. Видимо, такого размер карта отображается на каком-то стенде, но я даже не представляю, сколько она открывается.

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

Думай как…

Чтобы еще лучше понимать, как люди используют ваш API, вам нужно самим использовать API. Знаете, не просто абстрактно знать, как он работает, а постараться придумать задачу, которую бы решил разработчик при помощи вашего API. К примеру, так я не сколько лет назад пытался сделать приложение для Вконтакте — карту, на которой люди бы могли отмечать, где они путешествовали ранее.

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

Я постарался очистить сознание, в таком состоянии открыл документацию и пытался думать, как разработчик-пользователь.

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

Документируй это

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

API без документации — не API.

Документация — это документ, который подтверждает те публичные методы, которые должны обладать свойством обратной совместимости.

У нас есть, как справочник по всем методам, так и некоторые вводные статьи, к примеру, как подключить API или как создать карту. У нас документацию пишут сами разработчики через JSDoc.

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

Можно даже что-то подправить, а потом экспортировать в JSFiddle. Там можно посмотреть на живые примеры использования API: слева код, справа результат. Но и тут оказывается не все так просто, как могло показаться.

Однажды мы заметили такие карты.

Мы стали думать, почему так получилось, и оказалось, что так было в одном из наших примеров. На первый взгляд все в порядке, но если приглядеться, можно увидеть, что тут почему-то два элемента изменения масштаба (слева шкала, кнопочки справа). Разработчики просто копировали код как есть и вставляли себе на страницу. Мы хотели сделать пример с элементами управления на карте и подумали, что будет хорошей идеей добавить два зум контрола: «посмотрите, у нас есть большой зум контрол и маленький, работает так и так». То есть если есть кейс про поиск, то там будет только поиск, никаких дополнительных крутых опций, которые могут не потребоваться большинству разработчиков. После этого мы решили, что в примерах будем делать максимально живые кейсы.

Call me maybe

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

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

Продай мне эту ручку

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

На это тоже нужно тратить время.

Еще проще

Я начал рассказ с пункта «Будь проще», но можно пойти де еще дальше и вообще не заставлять разработчика программировать. Наиболее популярный кейс можно позволить решить через какой-нибудь специальный инструмент. К примеру, нашим популярным кейсом является просто отображение карты на странице или отображение карты на странице с какой-то меткой. Поэтому мы сделали конструктор.

Человек открывает карту в браузере, накликивает метки, рисует линии и полигоны, задает описание и получает код для вставки на сайт.

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

Конструктор

  • Простое решение популярных задач
  • Меньше «свободы» для разработчика
  • Обход ограничения обратной совместимости

По сути, конструктор является упрощенной версией API, им могут пользоваться даже не разработчики, поэтому мы в нем даем меньше «свободы». И это намеренный шаг. Сейчас я поясню.

<script src="
.../constructor/?um={id}&width=514&height=326 "></script>

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

Если человек не может ничего контролировать, как в данном случае, то мы можем делать все, что угодно. Мы это сделали намеренно, потому что это очень хороший способ обойти ограничения обратной совместимости. 0 на 2. Например, в этом виджете мы спокойно переключили версию с 2. Если бы мы оставили возможность программно что-то редактировать, то мы дали бы большую степень свободы разработчикам и соответсвенно, это привело бы к каким-то неопределеностям и ошибкам. 1 и не поступило вообще ни одной жалобы.

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

Итог

Как я уже говорил:

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

Напоследок, пара интересных ссылок:

Следующий Frontend Conf совсем скоро, 28 и 29 мая нас, как всегда, ждет много интересного и даже холиварного, например, вот несколько принятых докладов:

  • Chris Lilley (W3C). WebFonts in 2018: Everything Changes.
  • Виктор Русакович (GP Solutions). Зачем мы переписываем приложение на Elm, и кто его знает?
  • Тимофей Лавренюк (KeepSolid). Как сделать веб приложение нативнее, а пользователя счастливее с помощью современных возможностей браузера.

Кстати, в этом году будет больше конференций — 4 и 5 октября мы организуем еще один Frontend Conf Moscow, как самостоятельное мероприятие. Подать заявку на доклад можно аж до 3 августа, если вы упустили такую возможность на РИТ++, а в течение мая можно забронировать билеты по себестоимости.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть