Вопросы проектирования API с использованием Django для задач ОС (REST vs RPC)

Фон:

У меня есть приложение, которое должно автоматизировать некоторую инфраструктуру & задачи на уровне ОС, которые происходят на сетевой файловой системе (например: монтирование томов, выключение / включение серверов, создание каталогов, перемещение данных, ssh-ing и т.д.). В конечном счете, существует множество команд на уровне ОС, которые должны быть выполнены в последовательности для каждого действия. Наш потребитель/клиент, скорее всего, не знает этой последовательности, но знает: "Я хочу выполнить задачу X".

Технологический стек: Python/Django

Мне поручили создать это приложение, но я в недоумении, как лучше всего подойти к модульности с точки зрения API и просто общего дизайна. В настоящее время у нас есть похожее приложение, которое представляет собой SOAP-стиль (rpc), но то, как оно написано, не очень модульно. Например, одна функция будет иметь тонну случайных жестко закодированных команд подпроцесса - это не тот подход, который я хочу эмулировать здесь.

Изначально я больше склонялся к REST API, поскольку Django имеет хороший плагин django rest framework, но у меня возникают проблемы с моделированием этих очень ориентированных на действия задач. Чем больше я читаю другие вещи в интернете, тем больше я прихожу к убеждению, что мне действительно нужно думать о каждом маленьком действии как о ресурсе, а клиент должен GET/POST/PUT к каждому из них, чтобы сохранить все очень модульным, но когда я уменьшаю это дальше, это выглядит так, что мне может понадобиться установить 15+ конечных точек для каждой необходимой ситуации, и клиент, вероятно, не захочет вызывать все 15 конечных точек, чтобы получить их отдельное поведение, которое они хотят. Учитывая это, переход на rpc, чтобы пользователи могли иметь одну конечную точку, которая "перемещает луну одним вызовом", возможно, тоже не лучший подход.

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

Вопрос 1:

Пример действия, которое наш клиент может захотеть вызвать, будет отвечать за ssh-соединение с удаленным сервером и выполнение команды. Как вы можете смоделировать это в REST?

Вопрос 2:

Как вы все моделируете действия файловой системы в своих приложениях?

Вопрос 3:

После рассмотрения вышеизложенного, кажется ли RPC лучшим вариантом?

Другое:

Любая другая помощь или обратная связь (даже в целом, очень ценится).

REST похож на SOAP в том смысле, что вы вызываете операции в SOAP, а REST просто отображает эти операции на веб-ресурсы и методы HTTP.

Например

z DoSSHStuffOnARemoteServer(x=1,y=2)

vs

POST /RemoteServer/SSHStuff {x:1,y:2}

Если это таймаут, потому что это занимает много времени, тогда вы можете сделать

202 accepted
{type: "transaction": href: "/RemoteServer/SSHStuff/123", status: "pending"}

и опрашивайте его каждые 5-10 минут или используйте websockets для обновления статуса. После того, как это будет сделано:

200 ok
{type: "transaction": href: "/RemoteServer/SSHStuff/123", status: "done", result: {z:3}}

Так что никакой магии нет. Просто имейте в виду, что REST находится в презентационном слое вашего приложения, он возвращает модели представления, и вся структура связана с сервисами приложения, если вы делаете DDD. Он не должен отражать структуру базы данных, если только у вас не анемичная доменная модель, или другие называют это толстым клиентом. Обычно я ничего не говорю о RemoteServer/SSHStuff, просто говорю клиенту, что будет сделано, и молчу о том, как это будет сделано. Им не нужно ничего знать о том, как вы храните данные или сколько у вас серверов с какими протоколами и приложениями. Это не должно их волновать. Единственное, что им нужно знать, что будет сделано, сколько времени потребуется на ответ и каким будет ответ. Остальная часть не имеет для них никакого значения, и если вы поделитесь слишком большим количеством информации, это будет представлять угрозу безопасности. Когда мы разрабатываем интерфейс, например, интерфейс для REST-сервиса или просто интерфейс ООП, мы всегда делаем это, чтобы скрыть детали реализации. Надеюсь, это поможет, хорошего дня!

Вернуться на верх