Мне нужна идея реализации 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}}
Более безопасная ставка заключается в том, чтобы просто выбросить ошибку проверки, если пользователь пытается оснастить больше копий элемента, чем они есть, без замены одного из других во время изменения.