Мне нужна идея для RESTful реализации инвентаризации API для игры RPG - PullRequest
10 голосов
/ 23 февраля 2010

Я работаю над некой 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 для этого?

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

Ответы [ 4 ]

4 голосов
/ 23 февраля 2010

Поскольку в REST вы всегда должны действовать на ресурсе или на коллекции ресурсов, в этом случае я бы рассматривал действие ' MOVE ' как ресурс REST. Поначалу это может показаться неправильным, поскольку мы считаем « MOVE » глаголом, а не существительным, но это может иметь смысл, если интерфейс охватывает высокий уровень абстракции. В интерфейсе высокого уровня, который предоставляет опции, доступные пользователю для управления игрой, вы можете использовать « MOVE OPTION », которая внезапно становится существительным!

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

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

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

Если бы вы получили элемент из x и поместили его в y, где бы вы поместили логику проверки, которая проверяет, является ли y допустимым местом назначения? Это должно быть в модели (за интерфейсом) или в вашей игре? Если это должно быть в модели, то я думаю, что вы должны рассмотреть подход высокого уровня, который я описал ранее. Если, с другой стороны, вы намереваетесь обрабатывать эту логику в игре (перед интерфейсом), тогда вы можете использовать необработанный подход CRUD, как Ян предложил в другом ответе .

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

2 голосов
/ 23 февраля 2010

Виталий,

не думайте с точки зрения действий (переход), но с точки зрения ресурсов и передачи государства. Вот как я могу сделать то, что вы просите с 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

1 голос
/ 23 февраля 2010

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

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}} 

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

1 голос
/ 23 февраля 2010

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

так что я думаю, что вы должны положить на существующий элемент:

PUT /items/:id?position_id=:position_id

образец:

PUT /items/1?position_id=2

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

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

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

p.s. обратите внимание, что параметры после? НЕ ПОЛУЧИТЬ ПАРАМЕТРЫ:)

...