Здравствуйте, Sinclair, Вы писали:
O>>Я против ситуации, когда 500 может возвращаться кем-то еще, кроме серверного фронт энда.
S>Я уже пояснил вам, почему это не имеет смысла.
В рассмотренном примере этот факт не имеет значения.
O>>В описанном примере клиенту ничего анализировать как раз и не нужно. O>>4xx — ошибка формирования запроса. 2xx — запрос доставлен, можно переходить к следующему.
S>Погодите. Вы же говорите, что к следующему можно переходить, только если сервер его принял.
2xx — запрос обработан бэк эндом. Клиент переходит к формированию и отправке следующего.
4xx может означать только некорректно сформированные на уровне HTTP данные.
5xx — сервер недоступен, запрос следует повторить позже.
Все ясно, как день.
S>Ну, во-первых, вы лукавите. Попробуйте указать адрес страницы на диске в качестве атрибута action тега form. S>Так что HTML — даже сам по себе — вполне себе тесно связан с HTTP.
Это один из его недостатков. Такой же, как http-equiv в элементе meta.
S>Во-вторых, HTML — это не протокол. Это всего лишь один из форматов данных. Когда мы проектируем приложение, мы не только придумываем формат данных, мы определяем протокол — то есть соглашение, на основе которого клиентская часть взаимодействует с серверной. И вот как раз здесь — в протоколе — нам важно учитывать особенности среды, в частности полосу и латентность.
Да, все верно. На уровне HTTP мы используем сжатие, кэширование, даже контроль целостности.
А уровень данных играет по своим правилам. Я лишь предлагаю не смешивать их воедино, а
аккуратно изолировать друг от друга. При этом разница насколько тонкая, что остается
почти незаметной. Фактически, все различия сводятся только к тому, чтобы не использовать на
уровне данных (HTML/JSON/XML/другое) механизмы из нижележащего уровня (HTTP/TCP/UDP/другое),
такие как коды состояний или опции сжатия, а оставить их на совести того самого уровня, который ниже.
Впечатление, будто я призываю отказываться от встроенных механизмов HTTP — в корне неверное.
S>Не очень понятно, что вы имеете в виду под "прикладным протоколом поверх него". S>Я знаю два способа построить прикладной протокол поверх HTTP: S>1. Сделать вид, что HTTP — это такой UDP с более пушистой адресацией енд-поинтов и синхрнонными ответами. Игнорировать глаголы, статусы, кэширование, докачку, компрессию, шифрование, и прочие интересные вещи. Всё, что из потребуется, строить с нуля, игнорируя инфраструктуру. S>2. Использовать HTTP "как есть", потому что в нём из коробки есть почти всё, что может потребоваться современному клиент-серверному протоколу, и ещё 100500 вещей, о которых велосипедостроителей задуматься даже не успел. S>В тех редких случаях, когда семантики изкоробочного RFC 2616 недостаточно, пользоваться заложенными заранее точками расширения.
S>По ряду признаков мне кажется, что вы предпочитаете способ №1.
Это вовсе не так. Прокомментировал выше.
S>Вот как раз пытаться "прогнуть" HTTP, отдавая, скажем, 200 Ok вместо ошибки — это прямой способ нарваться на прокси, который посчитает себя умнее вас, и проигнорирует модные хидеры, которыми вы пытаетесь его контролировать.
Давайте рассмотрим еще один (очень упрощенный) пример.
Допустим, есть веб-сервис покупок, через который я POST-запросом могу заказать себе, скажем,
ящик водки. При успешном заказе сервер возвращает 200 OK, а с моего счета списывается некая сумма.
В определенный момент мой баланс становится нулевым и денег на водку не хватает — на очередной
запрос сервер должен возвратить что ? "200 OK" или "400 Bad Request" ? Допустим, первый вариант.
Объясните, почему прокси вдруг должен закэшировать ответы с кодом 200, но при этом передавать
ответы с кодом 400 мимо кэша ? Требование идемпотентности к запросам POST не предъявляется.
А по поводу кода 400 в RFC 2616 сказано: "The client SHOULD NOT repeat the request without
modifications" — клиенту не рекомендуется повторять тот же самый запрос, не включив в него
модификации. Как раз в этом случае прокси с большей вероятностью закэширует ответ-400 на
один и тот же запрос и будет все время его возвращать.
У нас разное понимание семантики кода 200.
Я считаю, что код 200 — это "запрос обработан". Или, точнее говоря, "сообщение доставлено".
Что это за запрос и что это за сообщение — уже не забота HTTP.
S>Ок, тогда я не понял, что вы называете "логической ошибкой", а что — "ошибкой транспорта".
Ошибка транспорта — это когда в GET-запросе не указывается URL или Host.
Логическая ошибка — это когда я пытаюсь заказать водку, а денег на счету нет.
S>Вот у нас на бэк-енде вылетел StackOverflowException. Какой код вы предлагаете возвращать в таком случае?
Код из группы 500, понятное дело. Запрос не был обработан бэк эндом, для клиента
это достаточная для принятия нужного решения информация.