
Лучшие фреймворки и API извлекаются из живых проектов

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

Админка как эталонное приложение
Много лет назад, когда мы только начинали создавать voximplant, у нас была большая стопка хотелок от клиентов и понимание того, что с первого раза хорошее API сделать не получится. Но очень хотелось. И во время очередного мозгового штурма родилась странная идея: сделать админку для разработчиков не на backend, как тогда делали для большинства проектов, а на frontend. И чтобы админка для всех своих функций использовала то же HTTP API, что мы даем нашим клиентам.

Безусловно, такой подход подойдет не для всех. Разработка “софта” — очень большая область. Есть разработка по спецификации заказчика, когда все API целиком дизайнится специально обученной командой архитекторов. Есть ситуации, когда API отражает лишь небольшую часть функциональности платформы, доступную для внешних разработчиков “песочницу”. Есть разработка по контракту, когда все нужно продумать и рассчитать заранее, чтобы спрогнозировать сроки и бюджет.
Тем не менее, нам этот способ очень хорошо помог. И, насколько я вижу в интернете, все больше и больше сервисов с развитым API придерживаются принципа “eat your own dog food”, используя эти API и для разработки собственных админок и сервисов. Пока у стартапа нет исчерпывающей документации и обучающих материалов на все случаи жизни, на вопрос клиента “а как сделать так-то” всегда можно ответить — “сделайте действия в админке и посмотрите в chrome dev tools какие запросы и с какими аргументами она выполняет”. Такой подход работает — и работает хорошо.
Дальнейшая эволюция: как использовать AttachPhoneNumber
Админка — штука хорошая, но для многих сервисов она позволяет делать только наиболее популярные операции, тогда как “сложные” кейсы остаются под капотом или доступны по API. В качестве примера я покажу нашу API функцию /AttachPhoneNumber которая позволяет арендовать номер телефона, чтобы в дальнейшем с помощью javascript сценариев управлять приходящими на этот номер звонками. В админке при покупке номера можно отфильтровать доступные номера по странам/типам/городам, выбрать понравившийся номер или указать количество номеров для аренды, а затем кликнуть на кнопку “купить”:

Если посмотреть на нашу документацию для соответствующего метода API, то можно легко найти соответствие между тем, что мы видим в интерфейсе и тем, что можно передать в API функцию:
- Разные варианты авторизации. Они одинаковы для большинства методов API и описаны в документации.
- В phone_count передается количество номеров, которые мы хотим арендовать за один запрос: от одного и до… сколько есть.
- В country_code при передается код страны, для России это будет “RU”, полный список можно посмотреть… да, в той же админке:

- В phone_category_name передается категория номера: прямой городской, мобильный, 8-800- и так далее. Список категорий также можно подсмотреть в админке или получить для указанной страны с помощью функции API GetPhoneNumberCategories — например, для городских номеров России это будет “GEOGRAPHIC”.
- В phone_region_id передается “идентификатор региона”. Это некий внутренний идентификатор, который используют телекомы разных стран, предоставляющие номера. Список традиционно можно подсмотреть, но лучше все-таки получить с помощью специального API GetPhoneNumberRegions, которое возвращает список доступных регионов для указанной страны и категории номера.
- В телефонной адресации некоторых стран региона недостаточно, и для таких стран при покупке нескольких номеров в параметре country_state передается идентификатор штата. Список штатов можно получить с помощью GetPhoneNumberCountryStates — для тех стран, где они есть.
Как можно видеть, все эти значения являются отражениями соответствующих полей формы и добавлялись по мере добавления функциональности: сначала была возможность покупать по номеру, затем мы добавили выбор количества номеров, который потянул за собой необходимость указывать какие номера интересуют клиента, затем появились партнеры и возможность покупки по номеру устарела — и так далее.
Как получить номер в Японии и ответить на звонок

Для начала нам понадобится выяснить количество доступных номеров — вдруг Токио закончился? Для авторизации используем идентификатор аккаунта и ключ из настроек админки voximplant, а для запроса количества номеров — специально обученный метод GetPhoneNumbers:
curl "https://api.voximplant.com/platform_api/GetNewPhoneNumbers/?account_id=1&api_key=2&country_code=JP&phone_category_name=GEOGRAPHIC&phone_region_id=8384"
В ответ получаем
curl "https://api.voximplant.com/platform_api/AttachPhoneNumber/?account_id=1&api_key=2&country_code=JP&phone_category_name=GEOGRAPHIC&phone_region_id=8384&phone_count=1"
После пары секунд раздумий мы получим JSON с параметрами арендованного номера, выглядит он вот так:
{
"result":1,
"phone_numbers":[
{
"phone_number":"81345793488",
"verification_status":"VERIFIED",
"phone_id":9033
}
]
}
В ответе мы можем видеть сам номер (мне достался 81345793488). В этом номере “+81” — код Японии, “3” — код Токио (обратите внимание — он не совпадает с идентификатором регионом для Токио, который мы задавали как “8384”, потому что идентификатор региона — это внутренний идентификатор телекома) и “45793488” — собственно сам номер. Чтобы принять на него звонок и сделать что-нибудь полезное нужно связать его с одним из приложений voximplant — которые тоже можно создавать через API. Пример такой команды, которая свяжет арендованный номер с приложением “foo” (да, у меня есть такое приложение. Оно говорит “привет” и вешает трубку):
curl "https://api.voximplant.com/platform_api/BindPhoneNumberToApplication/?account_id=1api_key=2&phone_number=81345793488&application_name=foo"
Надеемся, что этот небольшой кейс добавит в вашу копилку приемов веб разработки небольшой трюк — возможно, когда-нибудь в будущем такой подход спасет вас от множества бессонных ночей, проведенных за дизайном “идеального api”. В комментариях я традиционно готов ответить на неконструктивную критику, ответить на каверзные вопросы и просто пообщаться на тему дизайна и разработки API.