Подтвердить что ты не робот

Как должна выглядеть схема URL REST для иерархии деревьев?

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

GET http://server/stores/123/shelves/456/products

Отсюда, как я могу получить индивидуальный продукт? Должен ли я использовать:

GET http://server/products/789

Или:

GET http://server/stores/123/shelves/456/products/789

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

Аналогично, что относительно операции PUT/DELETE?

DELETE http://server/stores/123/shelves/456/products/789

Или:

DELETE http://server/products/789

Каким будет правильный способ проектирования схемы для иерархии дерева, например:

P.S. Если я что-то не понимаю о архитектуре REST, просьба привести примеры того, как я могу сделать это лучше. Там слишком много людей, которые любят говорить "ОТДЫХ - это не CRUD" и "REST не RPC", а затем не дают абсолютно никаких пояснений или примеров хорошего дизайна RESTful.

4b9b3361

Ответ 1

Не создавайте REST api на основе структуры URL. Здесь, как я думаю, вам стоит подумать о разработке REST api.

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

Ответ 2

Я отметил два подхода к дизайну URI RESTful: иерархический и отфильтрованный

Я чувствую, что иерархичность слишком многословна, имеет потенциал для избыточных конечных точек (не DRY) и маскируется в том, какое состояние ресурса вам действительно интересно (в конце концов, передача REST = репрезентативная).

Я предпочитаю простые URI

Простой элегантный. Я бы выбрал структуру URI, например

GET http://server/products/789

потому что меня интересует состояние ресурса продукта.

Если бы я хотел, чтобы все продукты, принадлежащие определенной полке в определенном магазине, я бы сделал

GET http://server/products?store=123&shelf=456

Если бы я хотел создать продукт в определенном хранилище на определенной полке, я бы опубликовал

{
    product: {
        store: 123,
        shelf: 456,
        name: "test product"
    }
}

с помощью

POST http://server/products

В конечном счете, это tomayto, tomahto

REST не требует одного над другим. Однако, по моему собственному опыту, более эффективно использовать RESTful API, который отображает отдельные объекты в одиночные конечные точки (например, сопоставления объектов RestKit на iOS) вместо того, чтобы иметь карту сущности для множества разных конечных точек на основе того, какие параметры переданы.

О REST

Что касается REST, это не протокол и не имеет RFC. Он тесно связан с HTTP/1.1 RFC как способ реализации своих CRUD-действий, но многие разработчики программного обеспечения полагают, что REST не зависит от HTTP. Я не согласен и считаю такой гипотезой, потому что оригинальная диссертация UCI Roy Fielding (http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm) объясняет глубоко укоренившееся соединение REST и HTTP/1.1. Вы также можете узнать мнение Роя по теме: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven.

Принципы, определенные REST, могут применяться к другим протоколам, но REST был создан для Интернета, а HTTP - протокол для всемирной сети.

REST vs RPC

RPC - это вызов вызовов удаленным функциям и ориентированный на глагол.

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

Вы можете выполнить те же действия с REST или RPC, но REST следует принципам DRY, потому что для каждого URI вы можете выполнять 4 действия, тогда как RPC требует конечной точки для каждого действия.

PS

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

Ответ 3

Создание продукта должно быть просто POST для

http://server/product

Обновление продукта должно быть PUT до

http://server/product/$id

Получение продукта должно быть просто GET для

http://server/product/$id

Удаление продукта должно быть просто DELETE для

http://server/product/$id

Вы должны использовать методы http, которые помогут вам получить больше функциональности из более простой структуры uri. Если для создания продукта требуется прохождение в магазине и полке в качестве требования, тогда они должны пройти через тело вашего POST (или PUT, если вы меняете полки).

Когда кто-то делает GET до http://server/product/$id, они вернут какой-то ответ xml/json, правильно? На что это похоже? Входящие данные для создания или обновления должны быть POSTED или PUT одинаково в теле запроса. Так вы проходите в магазине и на полке, а не через uri. Ури должен быть как можно более простым и просто указывать на ресурс (продукт), используя http-глаголы для дифференциации функциональности.

Если вы хотите получить содержимое полки 23, вы получите GET для

http://server/shelf/23

Когда вы это сделаете, вы вернете документ типа json/xml/custom media type с полными данными и коллекцией элементов продукта со ссылками на их uri продукта.

Если вы хотите перенести продукт 23 с одной полки на другую, вы выполните PUT для

http://server/product/23 

В теле PUT у вас есть продукт в представлении по вашему выбору, но с обновленной полкой.

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

Ответ 4

Так как продукты могут быть в нескольких магазинах или на нескольких полках (категории?), у меня будет каждый номер уникального номера, независимо от его положения в иерархии. Затем используйте плоский номер продукта. Это делает API более стабильным, когда некоторые продукты, например, перемещаются в вашем магазине.

Короче говоря, не добавляйте ненужную избыточность в ваш API. Для получения списка полки достаточно идентификатора магазина, для списка продуктов достаточно идентификатора полки... и т.д.

Ответ 5

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

http://server/product_info/123123 or http://server/product_info?product=123123
http://server/product_inventory?store=123&shelf=345

то вы также можете поддержать:

http://server/product_inventory?store=123

тогда PUT и DELETE имеют смысл для изменения инвентаря или добавления нового продукта.