RESTful API без идентификатора в URL-адресе

Я обсуждал лучший способ сделать это с одним из моих коллег

Вот пример сценария:

Я пытаюсь получить все заказы для Customer с идентификатором 1234.

Рассмотрим следующую конечную точку:

/клиент/заказы

С запросом GET со следующим заголовком:

Авторизация: Основной QWxhZGRpbjpvcGVuIHNlc2FtZQ ==

С заголовком Authorization наш механизм auth идентифицирует этот запрос как для Клиента с ID 1234, и наша служба возвращает требуемые заказы.

Он пытается убедить меня, что это правильно, потому что один из зарегистрированных в клиенте запросил только их заказы (в данном случае, приказы, принадлежащие клиенту 1234), поэтому передача идентификатора в URL-адресе не требуется. Однако.... Мне, это не RESTful (я могу ошибаться)

По-моему, это должно быть так:.

/customer/1234/orders

С заголовком (в качестве примера)

Авторизация: Основной QWxhZGRpbjpvcGVuIHNlc2FtZQ ==

С заголовком авторизации мы проверяем, что у пользователя есть разрешение на получение этих заказов... Если это так, верните их, иначе верните 401

Мой вопрос: какой предпочтительный метод?

Я могу, конечно, увидеть преимущества первого пути, но в интересах сохранения нашего api RESTful, мое сердце говорит, чтобы пойти со вторым способом...

Ответ 1

Я думаю, что вторая реализация (включая идентификатор клиента) необходима только в том случае, если вы позволите клиентам получать данные заказа других клиентов. Другими словами, если клиент 4321 сможет увидеть историю заказов клиента 1234, тогда отправка абсолютно необходима.

Думаю, они не смогут этого сделать. Это означает, что если вы включите эту информацию, вы, вероятно, будете игнорировать ее в пользу кода авторизации.

Если это случай, я говорю, даже не отправляю его.

Если это заставляет вас чувствовать себя лучше, LinkedIn REST API отражает это поведение. Любой пользователь может запросить профиль любого другого пользователя НО, если id опущен, он предполагает, что текущий пользователь запрашивает свой собственный профиль. Подробнее здесь

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

Ответ 2

Идентификация ресурсов является ключевым ограничением REST. Ваши заказы и мои заказы не являются одним и тем же ресурсом, поэтому они ДОЛЖНЫ (НЕ ДОЛЖНЫ) иметь другой идентификатор.

Практическая причина, по которой вам ДОЛЖНО предоставить им уникальный идентификатор (т.е./customers/1234/orders), заключается в том, что будет намного проще поддерживать кэширование HTTP. HTTP-кеширующие посредники в основном используют URI в качестве ключа кэш-памяти. Можно использовать другие заголовки (например, auth) как часть ключа кеша, используя заголовок переменной, однако поддержка таких механизмов намного менее надежна/широко распространена.

Даже если сегодня у вас нет планов использовать кеширование HTTP, лучше играть безопасно и обеспечить, чтобы ваши URI были разработаны, чтобы позволить эту возможность, если вам это нужно в будущем.

При выполнении конструкции URI на стороне клиента есть некоторые преимущества, чтобы не включать идентификатор клиента в URI. Тем не менее, системы RESTful должны предоставлять URI для клиентов, чтобы следовать, встраивая эти URI в возвращенные представления. Клиентам не нужно создавать эти URI, и, следовательно, есть дополнительная работа ZERO для клиентов, чтобы использовать URI с идентификатором, используя URI без Id. Если вы готовы усвоить таблетку гипермедиа, то нет никакого преимущества, чтобы не включать идентификатор.

Ответ 3

Ни один из них не является RESTful. Семантика URI должна быть неактуальной для клиента в приложении RESTful.

REST - это архитектурный стиль, основанный на самой веб-странице. Думаю об этом. Когда вы переходите в Stack Overflow, единственным URI, который вас беспокоит, является stackoverflow.com. После входа в систему вы перенаправляетесь на свою домашнюю страницу, а URI вашей домашней страницы не имеет значения. Прямо сейчас у меня в строке меню есть ссылка, которая идет на мою домашнюю страницу, у вас есть идентичная ссылка, которая идет на вашу домашнюю страницу, и нам все равно, что такое URI, когда мы нажимаем на него, не так ли? На нашей домашней странице мы видим вопросы и ответы, и нам также не нужны их URI, только их название и описание.

Теперь отмените его. REST being - это архитектурный стиль Интернета, если веб-сайт похож на ваш REST, когда вы присоединяетесь к stackoverflow.com, вместо того, чтобы иметь хорошую ссылку с вашим именем, указывающим на вашу домашнюю страницу, у вас будет текст с надписью "Your id 131809, пожалуйста, возьмите шаблон URI/users/(id), замените id этим номером, вставьте его в адресную строку, и вы попадете на свою домашнюю страницу", и вы думаете: "Почему эти идиоты не сделать ссылку для этого?"

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

Это означает, что вместо того, чтобы беспокоиться, если пользователь заказывает, должен быть в /customer/(customer_id)/orders или просто /customer/orders или даже /orders и полагаться на свои учетные данные, заставляя клиента знать все эти шаблоны URI, вы должны просто дать ему корневой документ в точке входа в API, который учитывает его учетные данные, и дает URI со стандартными заголовками и описаниями, как и любой веб-сайт при входе в систему!

Итак, скажем, вы используете JSON, а ваш API - myapi.com. Это должен быть единственный URI, который клиент знает. Когда он делает запрос GET к этому корневому документу с соответствующим заголовком авторизации, он должен получить документ JSON, например:

{"orders": "http://myapi.com/customer/123456/orders"}

И, очевидно, ему не нужно знать, что такое ценность "заказов", только то, что это допустимый URI, который приведет его к другому ресурсу, содержащему коллекцию его заказов. Этот URI может быть чем угодно, его семантика не имеет значения. Это может быть предложение вашего друга:

{"orders": "http://myapi.com/orders"}

Или что-нибудь еще, которое можно было изменить в любое время:

{"orders": "http://myapi.com/this/is/a/meaningless/uri"}

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

Ответ 4

Если вы используете идентификатор в вашем шаблоне /customer/[id] где-то в другом месте, было бы странно и непоследовательно опускать его для заказов только потому, что вы думаете прямо сейчас, что никто больше их не увидит.

Если только заказы, которые клиент когда-либо увидит, являются их собственными заказами, почему бы просто не использовать /orders? Таким образом, по крайней мере, вы избегаете этой несогласованности.

Однако я бы предпочел добавить идентификатор явно. Если в будущем кто-то из службы поддержки клиентов захочет просмотреть заказы, вам придется изменить URL-адрес или создать новый только для этой цели. Я рекомендую строго отделить идентификацию ресурсов от контентов прав доступа.