Мне нужна идея реализации RESTful API инвентаря для игры RPG

Я работаю над ролевой игрой. И я пытаюсь выяснить хороший, чистый и RESTful способ определения API инвентаризации.

инвентарь состоит из нескольких slots, таких как head, chest и т.д. (как в большинстве игр для RPG).

Теперь мне нужно определить REST API для перемещения всех элементов из слота X в слот Y.

несколько идей, которые у меня были:

  • ну, очевидно, инвентарь живет в /inventory
  • поэтому первая идея заключалась в том, чтобы иметь что-то вроде /inventory/movement и иметь CREATE, чтобы сделать его CRUD. поэтому он будет POST /inventory/movement. это будет CRUD и REST, но это очень плохо.
  • другой должен был иметь некоторые волшебные атрибуты в инвентаре и просто обновлять его: PUT /inventory?move_from=A&move_to=B. Это все еще не очень хорошо.

Итак, какая-нибудь идея для чистого решения CRUD REST для этого?

UPDATE: просто был другой: PUT /inventory/:to_slot?from=:from_slot - не уверен. почему действие происходит только на одном слоте, когда задействованы 2? хм... тьфу!

Ответ 1

Так как в REST вы всегда должны действовать на ресурсе или в наборе ресурсов, в этом случае я бы рассмотрел действие MOVE как ресурс REST. Сначала это может выглядеть некорректно, поскольку мы считаем " MOVE" глаголом, а не существительным, но это может иметь смысл, если интерфейс покрывает высокий уровень абстракции. В интерфейсе высокого уровня, который предоставляет доступным для пользователя опциям для управления игрой, вы можете захотеть воздействовать на " ВАРИАНТ ПЕРЕМЕЩЕНИЯ", который внезапно становится существительным!

Поэтому я использовал бы глагол POST для перемещения элемента в инвентаре, так как мы будем выдавать запрос на создание нового действия MOVE. Рассмотрим следующие убедительные примеры:

- POST /move/inventory/a/b
- POST /sell/inventory/a
- POST /use/inventory/b

Команда MOVE 'в сырых операциях CRUD обычно реализуется с помощью CREATE, за которым следует DELETE. Тем не менее, я думаю, вы обнаружите, что это слишком низкоуровневое, если вы должны использовать необработанные операции CRUD в таких игровых ресурсах.

Если вы должны ПОЛУЧИТЬ элемент из x и PUT его в y, где бы вы поместили логику проверки, которая проверяет, является ли y действительным адресом назначения? Должно ли оно находиться в модели (за интерфейсом) или внутри вашей игры? Если это должно быть в модели, то я думаю, вы должны рассмотреть подход высокого уровня, который я описал ранее. Если, с другой стороны, вы намерены обрабатывать эту логику в игре (перед интерфейсом), тогда вы можете взять исходный подход CRUD, поскольку Ян предложил в другом ответе.

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

Ответ 2

Виталий,

не думают с точки зрения действий (переход к), а с точки зрения ресурсов и передачи состояния. Вот как я буду делать то, что вы просите с помощью REST:

GET /game/inventories/5536

200 Ok
Content-Type: application/rpg.inventory+xml

<inventory>
  <slot href="/game/inventories/5536/slot">X</slot>
  ....
</inventory>





PUT /game/inventories/5536/slot

Content-Type: text/plain  (or what you need)

"Y"

GET /game/inventories/5536

200 Ok
Content-Type: application/rpg.inventory+xml

<inventory>
  <slot href="/game/inventories/5536/slot">Y</slot>
  ....
</inventory>

Но могут быть и другие способы.

Jan

Ответ 3

Он должен обновить position_id ipotetic Item внутри логики домена или что-то подобное, не так ли?

поэтому я думаю, что вы shuld PUT для существующего элемента:

PUT /items/:id?position_id=:position_id

Пример:

PUT /items/1?position_id=2

вы уже знаете "позицию из", потому что она должна быть уже определена в вашей модели товара, не так ли?

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

PUT /inventory/items/:id?position_id=:position_id

p.s. обратите внимание, что параметры после? не являются параметрами GET:)

Ответ 4

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

Перемещение RESTful из слота A в B может быть чем-то вроде

 PUT /inventory with params:

 {inventory => {:worn_on_head => nil, :worn_on_left_arm => @item}}

Вы могли бы упростить параметры с проверками и обратными вызовами или даже самими аксессуарами, чтобы гарантировать, что один и тот же элемент не находится в нескольких слотах. По существу, сокращение параметров для запроса перемещения на что-то вроде:

 PUT /inventory with params:

 {:inventory => {:worn_on_left_arm => @item}} 

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