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

В своем выдающемся докладе, сделанном в Google в 2007 г., инженер-программист и технический автор Джошуа Блох утверждал, что API — это очень важный бизнес-ресурс. В первую очередь потому, что если API открыт для клиентов, они могут вложить в него значительные средства, что затруднит им отказ от него. И наоборот, «плохо спроектированные API могут вызвать бесконечный поток обращений в службу поддержки, что крайне затруднит развитие компании».

Блох, который руководил разработкой и внедрением многочисленных функций платформы Java, включая Java Collections Framework, также отметил, что «мышление в терминах дизайна API, как правило, улучшает качество программ, которые вы пишете».

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

Однако дизайн API — это та область, с которой многие программисты испытывают трудности. Так каковы же характеристики хорошего API?

Имена имеют решающее значение

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

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

«По-настоящему хорошие названия позволяют обойти проблемы и предотвратить недопонимание, потому что правильное название дает понять, что это такое», — говорит Гарри Ричардсон, главный научный сотрудник SoftIron.

Он обращает внимание на то, что названия формируют ментальную модель для разработчиков. «Это довольно большая работа — взять и изменить ментальную модель, не в плане кода, а в плане того, как вы думаете о вещах», — отмечает он.

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

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

Избегайте загадочных сокращений, которые не имеют смысла, и следите за отсутствием последовательности, например, использования нескольких слов, которые означают одно и то же. Например, если вам нужно вернуть базовую зарплату для данного сотрудника, избегайте создания двух методов, таких как getBasicSalary() и getBaseSalary() — если в вашем API есть метод remove() и метод delete(), понимаете ли вы разницу, да и есть ли она вообще?

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

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

Если вы работаете с системой в стиле REST, стоит обратиться к уже существующему набору руководств по API, поскольку они могут помочь вам обеспечить последовательность в поведении API, советует Дэниел Брайант, независимый консультант и соавтор книги «Mastering API Architecture». Для API на основе HTTP он рекомендует использовать OpenAPI, а также Atlassian, Google, Microsoft и др.

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

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

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

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

Принцип наименьшего удивления

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

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

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

Также лучше избегать добавления чего-либо ради добавления. «Если сомневаетесь, не добавляйте», — говорит Блох. Обычно вы можете добавить что-то в API, если это покажется нужным, но вы никогда не сможете удалить что-то, когда API станет общедоступным.

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

«В конечном счете главное, чтобы API отражал реальность, — говорит Ричардсон. — Например, у человека может быть несколько адресов или номеров телефонов. И если в данный момент вас волнует только один адрес, желание указать только его — это искажение реальности. А игнорирование реальности всегда обойдется боком».

API — это навсегда

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

«К разработке API нужно подходить гораздо тщательнее, чем к чему-либо другому, — говорит Ричардсон, — потому что после создания API вы уже не сможете его изменить».

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

«Если произойдет утечка детали реализации, вы не сможете ее изменить, — говорит Ричардсон. — Поэтому вам нужно подумать, какие операции здесь выполняются? Что на самом деле представляет собой структура данных?»

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

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

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

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

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

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

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

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

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