Здесь есть несколько хороших ответов, но я не уверен, что они помогут вам убедить коллег. Как уже отмечали многие, то, что вы предлагаете, не является отходом от дизайна RESTful, и я думаю, что это ключ к тому, чтобы привлечь их к вашему предложению.
REST не гарантирует, что ваш API позволяет только хранить и извлекать данные. Скорее, это связано с моделированием действий как ресурсов. Ваш API должен позволять выполнять действия (в конце концов, это интерфейс прикладного программирования ). Вопрос в том, как смоделировать эти действия.
Вместо того, чтобы придумывать термин, примеры, вероятно, являются лучшим способом объяснить это вашим коллегам . Таким образом, вы можете показать, как они это делают сейчас, какие проблемы это вызывает, решение, которое решает проблему, и как оно все еще остается RESTful.
Давайте посмотрим на ваш объект Customer.
Проблема:
Пользовательский интерфейс отправляет клиенту, но последующие таблицы еще не были обновлены. Что если один из последующих вызовов завершится неудачно из-за ошибки в вашем коде пользовательского интерфейса (или неправильного поведения плагина браузера и т. Д.)? Теперь ваши данные находятся в противоречивом состоянии. Это может быть даже состояние, которое нарушает другие части вашего API или пользовательского интерфейса, не говоря уже о том, что оно просто недопустимо. Как вы поправляетесь? Вы должны проверить каждое возможное состояние, чтобы убедиться, что это не сломает что-то, но было бы сложно узнать, что это возможно.
Решение:
Создайте конечную точку API для создания клиентов. Вы знаете, что не хотите иметь конечную точку "/ customer / create" или даже "/ create-customer", потому что create является глаголом и нарушает REST. Так что назови это. "/ customer-creation" может работать. Теперь, когда вы размещаете свой объект CustomerCreation, он отправляет все необходимые поля для полного создания клиента. Конечная точка будет гарантировать, что данные полны и действительны (возвращая 400 или что-то, если они не проходят проверку), и могут сохраняться все, например, в одной транзакции БД.
Если вам также нужна конечная точка для объектов GET / customer, это нормально. Вы можете иметь оба. Хитрость заключается в создании конечных точек, которые обслуживают потребности потребителей.
Преимущества:
- Вы гарантируете, что у вас не будет плохого состояния
- На самом деле разработчикам пользовательского интерфейса проще, если им не нужно «знать» порядок запросов, вопросы проверки и т. Д.
- Это не так болтливо API, что снижает задержку сетевых запросов
- Проще тестировать и концептуализировать сценарии (отсутствующие / искаженные фрагменты данных из пользовательского интерфейса не распределяются по запросам, некоторые из которых могут не работать)
- Это позволяет лучше инкапсулировать бизнес-логику
- Как правило, упрощает безопасность (поскольку бизнес-логика и логика в пользовательском интерфейсе могут быть изменены пользователями)
- Скорее всего, уменьшит дублирование логики (более вероятно, что у вас будет более 2 потребителей API, чем 2+ API, которые предоставляют доступ к одним и тем же данным)
- Все еще 100% ОТДЫХ
Недостатки:
- Это потенциально больше работы для внутреннего разработчика (но может не быть в долгосрочной перспективе)
Людям может быть трудно понять эту парадигму и что в ней хорошего, если они не опробовали ее. Надеюсь, вы можете помочь им увидеть, используя пример из вашего собственного кода.
Мой собственный опыт показывает, что как только разработчики в моей команде начали реализовывать эту стратегию, они почти сразу увидели преимущества.
Дальнейшее изучение:
Эта статья от ThinkWorks действительно помогла мне получить представление о моделировании действий как объектов на практических примерах: https://www.thoughtworks.com/insights/blog/rest-api-design-resource-modeling.
Я бы также предложил почитать CQRS и Event Sourcing, так как они касаются именно такого рода вещей (то есть отделяют ваш API от фактической логики персистентности). Я не знаю, насколько готовы были бы ваши коллеги читать подобные вещи, но это может дать вам больше ясности и помочь вам объяснить это им.