Я думаю, что у вас может быть пользовательский процесс с несоответствием реализации здесь.
Во-первых: хочет ли пользователь честно выполнять несколько изменений в файле одновременно? Переименование (которое может включать или не включать изменение пути?), Изменение владельца и, возможно, изменение содержимого файла (ради аргумента) кажутся отдельными действиями.
Давайте возьмем случай, когда ответ «да» - ваши пользователи действительно хотят внести эти изменения одновременно.
В этом случае, я настоятельно рекомендую против любой реализации , которая посылает несколько событий - RenameFileCommand
, MoveFileCommand
, ChangeOwnerCommand
- для представления этого одного намерения пользователя.
Почему? Потому что события могут потерпеть неудачу. Может быть, это крайне редко, но ваш пользователь отправил операцию, которая выглядела атомарно - если одно из событий ниже по потоку завершается неудачей, то состояние вашего приложения теперь недопустимо.
Вы также предлагаете расовые опасности на ресурсе, который четко разделен между каждым из обработчиков событий. Вам нужно будет написать «ChangeOwnerCommand» таким образом, чтобы имя файла и путь к файлу не имели значения, потому что они могут быть устаревшими к моменту получения команды.
При реализации неуправляемой системы отдыха с перемещением и переименованием файлов я предпочитаю обеспечить согласованность, используя что-то вроде системы eTag - убедитесь, что версия редактируемого ресурса - это версия, которую пользователь извлек в последний раз, и произойдет сбой, если она был изменен с тех пор. Но если вы отправляете несколько команд для этой однопользовательской операции, вам нужно будет увеличивать версию своего ресурса после каждой команды - поэтому у вас нет возможности узнать, что ресурс, который пользователь редактирует, действительно совпадает с версией ресурса, который он последний раз читал. ,
Под этим я подразумеваю, что если кто-то еще в тот же момент выполняет другую операцию над файлом. 6 команд могут складываться в любом порядке. Если бы у нас было только две атомарные команды, более ранняя команда могла бы завершиться успешно, а более поздняя команда могла потерпеть неудачу: «ресурс был изменен с момента его последнего получения». Но нет защиты от этого, когда команды не являются атомарными, поэтому целостность системы нарушается.
Интересно, что в REST наблюдается движение к чему-то похожему на событийную архитектуру, которая называется «Отдых без PUT», рекомендованной в технологическом радаре Thoughtworks в январе 2015 года . Здесь есть гораздо более длинный блог об отдыхе без PUT .
По сути, идея в том, что POST, PUT, DELETE и GET хороши для небольших приложений, но когда вам нужно начать предполагать, как put, post и delete могут интерпретироваться на другом конце, вы вводите связывание. (например, «когда Я УДАЛЯЮ ресурс, связанный с моим банковским счетом, этот счет должен быть закрыт»). И предлагаемое решение состоит в том, чтобы рассматривать REST более подробно, используя источник событий. т.е. позволяет POST пользовательское намерение как отдельный ресурс события.
Другой случай проще. Если ваши пользователи не хотят выполнять все эти операции одновременно, не позволяйте им. POST событие для каждого намерения пользователя. Теперь вы можете использовать etag-контроль версий на своих ресурсах.
Что касается других приложений, которые используют совсем другой API для ваших ресурсов. Это пахнет неприятностями. Можете ли вы построить фасад старого API поверх вашего RESTful API и указать их на фасаде? т.е. предоставить сервис, который выполняет несколько обновлений файла последовательно через сервер REST?
Если вы не создадите интерфейс RESTful поверх старого решения, не построите фасад старого интерфейса поверх решения REST и не попытаетесь поддерживать оба API-интерфейса, указывающие на общий ресурс данных, у вас возникнут серьезные головные боли.