2014-01-18 4 views
5

Я разрабатываю онлайн-игру, где персонажи могут выполнять сложные действия против других объектов и персонажей. Я создаю REST API и испытываю массу проблем, пытаясь следовать даже некоторым из самых базовых стандартов. Я знаю, что REST не всегда является ответом, но по разным причинам для меня имеет смысл использовать REST, так как остальная часть API использует его соответствующим образом.Как вы моделируете сложные операции в REST?

Вот некоторые хитрые примеры:

GET/символы/боб/пункты Это возвращает массив элементов, которые Боб несущих.

Мне нужно выполнить множество «операций» против этих предметов, и им очень сложно моделировать это как «ресурсы».

Вот некоторые потенциальные операции, в зависимости от характера этого пункта: броска, есть, падение, провести

Это осложняется тем, что эта «операция» являются подходящим только для определенных элементов. Например, вы не можете есть меч. Более того, «есть» по существу имеет побочный эффект «удаления» ресурса. Использование «throw» также может «удалить» ресурс. Использование «drop» может «преобразовать» ресурс в другой тип ресурса. «Бросок» требует, чтобы я предоставил «местоположение». «Удержание» требует, чтобы я подавал руку для хранения элемента. Итак, как вы моделируете эти операции в качестве ресурсов? Ни один из них не является «одинаковым», потому что каждый из них требует разных параметров и приводит к совершенно различным поведением.

В настоящее время у меня есть ресурс «действия», к которому я отправляю эти произвольные действия. Но это чувствует себя слишком RPC и нестандартизированное/познаваемым:

POST/действия/бросить { characterId: 5, Itemid: 10, х: 100, у: 150 }

ответ

6

I старайтесь придерживаться ресурсов и GET/POST/PUT/PATCH/DELETE, где это возможно, но базовые глаголы имеют тенденцию напрямую сопоставляться с вызовами CRUD. Другие, более сложные операции обычно не могут быть сопоставлены без дополнительной информации.

Сосредоточение на ресурсы, я бы, вероятно, сделать что-то вроде этого (отправка сообщений на ресурсы):

POST /characters/bob/items/{bombId}?action=throw 
POST /characters/bob/items/{foodId}?action=eat 
POST /characters/bob/items/{potionId}?action=add&addedItem={ingredientId} 

возвращает ошибку, когда действие не подходит для данного пункта.

+0

Я не совсем уверен, что понимаю этот подход. Какое «состояние»/«представление»/«ресурс» я изменяю с помощью этого типа POST?Это похоже на RPC, потому что параметр запроса в конечном счете диктует «схему» ожидаемого POST. – user43823

+1

Ваш ресурс является используемым объектом (это то, что вы изменяете). Не думайте о параметре действия в качестве запроса - я думаю об этом как о заменяющем глаголе. HTTP/REST не предоставляет глагол EAT, но action = eat пытается смоделировать это. Я думаю, что сложные, многоресурсные сообщения просто сложно хорошо моделировать. Я скажу, что «POST/actions/throw» кажется мне похожим на RPC. –

+0

@MikeDunker: вместо создания нового глагола вы можете создать ресурс (сбор) 'meal' /' eatings' и 'POST' новый элемент, то есть:' POST/characters/bob/eatings' с '{item: X}' , Или вы можете создать более общий ресурс 'operations', а затем' POST/characters/bob/operations' с '{name: 'eat', item: X}'. – marcinn

1

Где я хочу, чтобы ресурс «выполнял сложное действие», оставаясь RESTful, я бы поставил сложный документ на ресурс, который описывает, что я хочу. (Сложный документ может быть в формате XML, JSON или в любом другом формате.) Это несколько отличается от более распространенного шаблона сопоставления POST для «создания дочернего ресурса», но значение POST «do non- idempotent действие, определяемое содержимым тела ". Это разумно подходит для вас.

Как часть принципа обнаружения HATEOAS, когда вы получаете доступ к ресурсу, который вы позже отправите POST, часть возвращаемого документа должна сказать, что представляют собой эти сложные документы действий и куда их следует отправлять. Логически, подумайте о заполнении формы и ее отправке (даже если «форма» на самом деле является слотом в документе JSON или что-то в этом роде).

 Смежные вопросы

  • Нет связанных вопросов^_^