С наступившим Новым годом! Всем профессиональных успехов и развития в новом году!



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



Вот, например, руководства по стилю REST API. Как мы все знаем, REST -- это просто набор архитектурных принципов, но, когда доходит дело проектирования конкретных API, возникает множество мелких вопросов. Иногда совсем мелких: какой регистр использовать для названий полей в json? А в названиях эндпоинтов? А имена ресурсов писать во множественном числе или в единственном?



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



Образцы таких гайдлайнов, как ни странно, можно найти у правительств разных стран. Они есть у Австралии, Новой Зеландии, Канады, Великобритании, у США конечно. Но мне больше всего нравится бельгийский гайдлайн: https://www.belgif.be/specification/rest/api-guide . Он и устроен наиболее логично, и как-то по-человечески, что ли. И при этом учитывает разнообразные аспекты, о которых и вправду стоит подумать.



В частности, в нём есть:



👉🏻 формат для URI эндпоинтов: рекомендуется lowerCamelCase, без расширений файлов;

👉🏻 три типа ресурсов: документ, коллекция и контроллер.

Документ — единичная сущность, с которой можно делать CRUD, у неё есть id, URI и поля;

Коллекция — набор однотипных сущностей, с которыми можно делать только GET и POST, и в редких случаях DELETE - если мы хотим удалить все элементы сразу;

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

/{имя коллекции}/{id документа}/{имя подчиненной коллекции}/{id подчиненного документа}.

Ну а контроллер — это подчиненный ресурс документа, представляющий бизнес-операцию, не укладывающуюся в CRUD (примеры: POST /accounts/123/withdraw, GET /convertMoney?from=EUR&amount=45&to=USD). При этом для долгих операций рекомендуется создавать ресурс типа документ, и уметь возвращать промежуточный статус операции (превращая её, таким образом, в асинхронную).



👉🏻 спецификация дополнительных операций: для документов — ?select={(поле,(поле,поле))}, чтобы выбирать только указанные поля — убираем overfetching;

для коллекций — сортировка: ?sort={поля для сортировки} , пагинация: ?page, ?next, ?prev, ?pageSize= , полнотекстовый поиск: ?q={поисковый запрос}, фильтрация: ?{поле}={значение}.

👉🏻 механизм для встраивания ресурсов (возможности GraphQL в REST!): ?embed={название связанной сущности, которую мы хотим встроить в ответ}, убираем underfetching.

👉🏻 требования к идентификаторам документов: рекомендуется текст, URI или UUID, а вообще там множество нюансов: идентификатор должен хорошо запоминаться, легко вводиться, легко проверяться, распечатываться, подсказывать природу объекта (по структуре идентификатора), предупреждать коллизии, не содержать чувствительной информации, не быть легким для подбора (если идентификаторы выдаются последовательно - легко угадать предыдущие и последующие, и даже вычислить, например, количество сущностей), использоваться в разных системах, быть расширяемым, вставляться в URL, логичным образом сортироваться... То есть вообще непонятно, бывают ли идентификаторы, удовлетворяющие всем требованиям!

👉🏻 рекомендации по использованию кодов ошибок;

👉🏻 соглашение об использовании значений null в json (решение: не должны использоваться, чтобы не создавать неоднозначности; если значение null, то оно не передаётся. При этом [] — это не null!)

👉🏻 кэширование (по времени и по содержимому, управление через параметры заголовка:

👉🏻 эволюция и версионирование API (обсуждаются совместимые и несовместимые изменения)

👉🏻 интернационализация (фильтрация языка через ?lang={код языка})

👉🏻 отслеживание (Trace-Id в заголовках)

👉🏻 статус API (ресурс health)



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