Обновить
4

Неизвестный агрессивный человек

0,1
Рейтинг
2
Подписчики
Отправить сообщение

Без HATEOAS REST работает как RPC и концептуально от него мало чем отличается.

По словам Роя Филдинга, API квалифицируется как «RESTful», если соответствует следующим ограничениям:

Ссылку на слова Филдинга приведёте?

Может лучше просто читать через GET, и тогда вас все поймут?)

А гейтвей HTTP-HTTP это не прокси?

Не знаю стандартная это практика для PUT или нет, но PUT совсем не подходит для /echo. Клиенты априори не должы получать эхи, записанные другими клиентами.

Продолжая наш вчерашний флейм. Вы написали, что /users/{user_id} более правильно, чем /me, и далее


// Получение профиля
GET /user/{user_id}
Authorization: Bearer <token>


Теперь URL запроса в точности идентифицирует ресурс, к которому обращаются, поэтому можно организовать кэш и даже заранее наполнить его;
[...]
Наконец, неочевидная польза такого решения заключается в следующем: промежуточный сервер-гейтвей, обрабатывающий запрос, может проверить заголовок Authorization и переслать запрос далее без него (желательно, конечно, по безопасному соединению или хотя бы подписав запрос).

И что


Запрос «себя» должен (обязан) пробивать кэш, поскольку иначе можно получить доступ к чьим-то чужим данным.

  1. Вряд ли гейтвей может переслать запрос серверу без Authorization: A proxy forwarding a request MUST NOT modify any Authorization fields in that request
    https://greenbytes.de/tech/webdav/rfc7235.html#header.authorization


  2. Общий кеш нельзя использовать для ответов на запросы с Authorization: A shared cache MUST NOT use a cached response to a request with an Authorization header field.
    https://greenbytes.de/tech/webdav/rfc7234.html#caching.authenticated.responses



Когда клиент запрашивает собственный профиль, не важно, через /me или /users/{user_id}, обычно он ожидает получить в том числе непубличную информацию об профиле. Такой запрос всегда будет с токеном.

Мозилла неточна. Я загуглил этот вопрос и попал на ответ от Julian Reschke, одного из авторов спецификации HTTP.


So yes, responses for a succesful PUT can have a reponse body, but normally, it does not make sense to include one. (What for?).
https://stackoverflow.com/questions/63275986/meaning-that-put-method-successful-response-has-body-in-the-mdn-document


Так что мозилловская страничка была недалека от истины. Я тоже не понимаю, какой смысл должно иметь тело в ответе PUT, если в запросе мы все равно обязаны передать полное представление.

Сохраняет в память и возвращает обратно, всё совершенно логично.

Да не должен он ничего сохранять, представьте что /echo является stateless по определению. Негде ему это сохранять, и незачем.


PUT может иметь тело ответа, конечно.

Моzilla ошибается? https://developer.mozilla.org/ru/docs/Web/HTTP/Methods/PUT

Ну да. Разница в том, что GET возвращает представление адресуемой сущности, а POST не обязательно; он как раз задизайнен чтобы предоставлять доступ к сущностям, не имеющим прямого URL.

Ну, так и /echo вполне является адресумой сущностью с переменным представлением. POST задизайнен для того, чтобы его можно было использовать для любых других операций, не стандартизированных в рамках остальных методов. Как писал Филдинг, "POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.”"
https://roy.gbiv.com/untangled/2009/it-is-okay-to-use-post


Вы просто говорите, что индицировать одни эффекты (немодифицируемость, идемпотентность) считаете более важными, чем другие (некэшируемость, семантика глагола).

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


Запрос «себя» должен (обязан) пробивать кэш, поскольку иначе можно получить доступ к чьим-то чужим данным. С моей точки зрения это важнее, чем индикация идемпотентности.

Так можно сказать про любой авторизованный GET запрос. Не думаю что вы предлагаете заменять все такие читающие запросы на POST просто чтобы "пробить кеш".


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

Здесь я согласен :)

Это очень странно, потому что /echo априори ничего не записывает и ничего не сохраняет; PUT заменяет представление ресурса данными представленными в теле запроса, но что, если тело запроса будет пустым; кроме этого, ответ PUT тела не имеет.


Как вы себе это представляете? Делать PUT /echo, потом GET /echo? А если один клиент сделает PUT /echo, а другой сделает GET /echo?

Я же с вами абсолютно не спорю. Я всего лишь говорю, что, обращаясь к нему таким образом, вас интересует не внутреннее представление самого ресурса echo, а результат некоторого алгоритма, на который ссылается /echo. А для этого предназначен POST.

POST, как и GET, тоже возвращает представление, а представление может представлять результат обращения к ресурсу, или представлять состояние, в которое должен перейти клиент. Такого понятия, как "внутреннее представление" (хранимое?) в HTTP нет. Когда мы делаем GET https://habr.com/ru/post/560590/, мы понятия не имеем, возвращает ли этот ресурс "внутреннее представление", результат сложных вычислений или промежуточный ответ от другого сервера. Рандомные цитаты от GPT мы тоже должны через POST получать?) Получить свой адрес по http://ip.changeip.com/ тоже? А считывать метрологические данные https://tgftp.nws.noaa.gov/data/observations/metar/stations/UKLL.TXT тоже через POST? И лицо получать https://thispersondoesnotexist.com/ тоже?


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

Я бы просто использовал для этого Cache-Control, а не подменял бы смысл запроса на POST, давая знать, что этот запрос кроме чтения может иметь другие побочные эффекты.

Скорее сервис, чем документ. Хотя он может быть ни тем, ни другим.

Зачем? Ресурс /echo семантически не предназначен ни для чего другого, кроме извлечения информации; он безопасен; он идемпотентен. Клиент или любой промежуточный агент, зная, что GET идемпотентен, может сам повторить запрос при сбоях связи. А вы предлагаете отбросить эту семантическую информацию, использовав POST. Этой заменой ничего не выиграете.

Продолжая ваш ход мыслей. Представим ресурс /echo, который в теле ответа отражает запрос обратно клиенту — со всеми заголовками, как есть. Его тоже следует использовать методом POST?

Получается, что /me не указывает на некоторую «именованную сущность», как предписывает концепция ресурса.

Вряд ли она предписывает. Наоборот, REST определяет "ресурс" как семантику, а не как значение, которое соответствует этой семантике. Давайте просто сошлемся на источники:
REST accomplishes this by defining a resource to be the semantics of what the author intends to identify, rather than the value corresponding to those semantics at the time the reference is created.
https://www.ics.uci.edu/~fielding/pubs/dissertation/evaluation.htm#sec_6_2_1


This specification does not limit the scope of what might be a resource; rather, the term “resource” is used in a general sense for whatever might be identified by a URI. […] This specification does not place any limits on the nature of a resource, the reasons why an application might seek to refer to a resource, or the kinds of systems that might use URIs for the sake of identifying resources.
https://tools.ietf.org/html/rfc3986#section-1.1


The target of an HTTP request is called a “resource”. HTTP does not limit the nature of a resource; it merely defines an interface that might be used to interact with resources.
https://tools.ietf.org/html/rfc7231#section-2


Resources are not storage items (or, at least, they aren’t always equivalent to some storage item on the back-end). [...] Likewise, a single resource can be the equivalent of a database stored procedure, with the power to abstract state changes over any number of storage items.
https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven#comment-743


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

Мы сейчас на второй круг зайдем :) Хорошо, я отвечу вашими же словами:


Приведём простой пример. Пусть в нашей системе есть операции получения профиля пользователя и его удаления. Мы можем организовать их разными способами. Например, вот так:
// Получение профиля
GET /me
Cookie: session_id=<идентификатор сессии>

Ресурс /me возвращает профиль пользователя, который сделал этот запрос. Выше вы предложили сделать то же самое, но через POST /me. В чем разница?

Со stateless-принципом авторизация в принципе плохо дружит, сам Филдинг это признал в ныне умершей группе рассылки на yahoo:
I should note that the big conflict between REST and security models is the fact that REST does not allow for sessions. What needs to be understood is that sessions are bad for security models too – they cause most of the denial-of-service and man-in-the-middle attacks to be possible. What is needed is an efficient, session free means of authenticating that is more secure than username/password, which is actually an easy problem to solve if you don’t try to solve all of the security problems at once. What is blocking that is the need to negotiate security mechanisms before engaging in secure communication, which is currently done within a session.
https://web.archive.org/web/20191213070235/https://groups.yahoo.com/neo/groups/rest-discuss/conversations/messages/3661

Мы не меняем предусловия, /me возвращает авторизованный аккаунт исходя из переданного токена. Вопрос остается в силе. Почему POST?

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


Все-таки, вы можете привести конкретные отличия или противоречия?

Зачем использовать POST для чтения, если для этого есть безопасный, идемпотентный GET? И чем принципиально это отличается от GET /me?

Информация

В рейтинге
4 423-й
Зарегистрирован
Активность