2010-02-10 8 views

ответ

10

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

12

Это зависит от того, кто пишет код клиента. Если вы пишете клиент и сервер, то это не имеет большого значения. Вы либо будете страдать от создания URL-адресов на клиенте или на сервере.

Однако, если вы строите сервер, и вы ожидаете, что другие люди напишут код клиента, они будут любить вас гораздо больше, если вы предоставите полные URI. Устранение относительных URI может быть немного сложным. Сначала, как вы их разрешаете, зависит от возвращаемого типа медиа. Html имеет базовый тег, Xml может иметь xml: базовые теги в каждом вложенном элементе, каналы Atom могут иметь базу в фиде и другую базу в контенте. Если вы не предоставляете своему клиенту явные сведения об базовом URI, тогда они должны получить базовый URI из URI запроса или, может быть, из заголовка Content-Location! И следите за этой задней чертой. Базовый URI определяется игнорированием всех символов справа от последней косой черты. Это означает, что конечная косая черта теперь очень значительна при разрешении относительных URI.

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

7

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

+0

При условии, что вы определяете «абсолютный» как абсолютный путь (например, '/ xxx/yyy ...'), а не как полноценный URI (например, http://api.example.com/xxx/yyy .. .'). –

2

Один из недостатков использования абсолютных URI заключается в том, что api не может быть проксированным.

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

+3

Почему абсолютный URI не может использовать имя хоста прокси? –

+1

Работая по этой точной проблеме на данный момент.Мы хотим, чтобы все запросы сначала проходили через своего рода «выравнивание нагрузки». Абсолютные URI для серверов напрямую нарушают эту модель. – mag382

+0

Я использую Nginx для проксирования сайта с абсолютными URL-адресами. Он отлично способен заменить URL-адрес бэкэнд эквивалентным URL-адресом прокси-сервера. В частности, это проксинг https://windyroad.artifactoryonline.com (который имеет полностью квалифицированные URL-адреса и полностью квалифицированные переадресации) на https://repo.windyroad.com.au –

57

Существует тонкая концептуальная двусмысленность, когда люди говорят «относительный ури».

К RFC3986's definition, общий URI содержит:

URI   = scheme ":" hier-part [ "?" query ] [ "#" fragment ] 

    hier-part = "//" authority path-abempty 
      /path-absolute 
      /path-rootless 
      /path-empty 

    foo://example.com:8042/over/there?name=ferret#nose 
    \_/ \______________/\_________/ \_________/ \__/ 
     |   |   |   |  | 
    scheme  authority  path  query fragment 

Хитрая вещь, когда схема и полномочия опущены, «путь» часть сама по себе может быть либо абсолютный путь (начинается с «/») или «корневой» относительный путь. Примеры:

  1. абсолютный URI или полный URI: "http://example.com:8042/over/there?name=ferret"
  2. И это относительная Ури с абсолютным путем: "/ над/есть"
  3. И это родственник uri, с относительным путем: «здесь» или «./here» или «../here» или т. д.

Итак, если вопрос был «должен ли сервер производить относительный путь в успокоительной ответ», ответ «Нет» и detail reason is available here. Я думаю, что большинство людей (включая меня) против «относительного ури» на самом деле против «относительного пути».

И на практике большинство серверных MVC-фреймворков могут легко генерировать относительный uri с абсолютным путем, например, «/ absolute/path/to/the/controller», и вопрос становится «должен ли реализация сервера префикс схема: // hostname: порт перед абсолютным путем ». Как вопрос ОП. Я не совсем уверен в этом.

С одной стороны, я по-прежнему считаю, что сервер, возвращающий полный uri, рекомендуется. Однако сервер должен never hardcode the hostname:port thing inside source code like this (в противном случае я предпочел бы вернуться к относительной uri с абсолютным путем). Решение - это серверная сторона, всегда получающая этот префикс от заголовка HTTP-запроса HTTP. Не уверен, что это работает для всех ситуаций.

С другой стороны, для клиента не очень сложно конкатенировать "http://example.com:8042" и абсолютный путь. В конце концов, клиент уже знает эту схему и доменное имя, когда он правильно отправляет запрос на сервер?

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

+2

Это хороший ответ (+1), с которым я согласен, кроме окончательный вывод. Однако в своем ответе я утверждаю, что спецификация HTTP определяет * * на пример *, "absolute", чтобы ссылаться на абсолютный * путь *, а не на полный URI. Поэтому я не согласен с вашим (2) - это * является * абсолютным URI, но тем, для которого клиент должен вывести сетевой протокол и хост, поэтому он не является полностью квалифицированным URI. И, следовательно, я также не согласен с вашим определением (1), которое * как * полное URI, так и абсолютный URI. –

+0

Спасибо за комментарий. Я просто заимствую концепцию абсолютного пути и относительного пути из файловой системы. Разные термины друг от друга, я не вижу существенной разницы между вашим мнением и моим мнением. Вы также рекомендуем форму 1 и 2, а вы против формы 3, не так ли? – RayLuo

+2

Практически, я за (2); Я думаю, что (1) требует, чтобы бэкэнд имел много специфических знаний по HTTP (что означает детали конкретной HTTP-среды, а не HTTP в целом), и (3), кажется, требует слишком много от клиента. * Но *, мои рассуждения были основаны на исходной спецификации проекта, и примеры были изменены в более поздней версии таким образом, что недействительны мои рассуждения. –

3

Вы всегда должны использовать полный URL. Он действует как уникальный идентификатор ресурса, поскольку все URL-адреса должны быть уникальными.

Я также хотел бы утверждать, что вы должны быть последовательными. Поскольку HTTP-заголовок местоположения ожидает полного URL-адреса на основе спецификации HTTP, полный URL-адрес отправляется обратно в заголовок Location для клиента при создании нового ресурса. Было бы странно, если бы вы предоставили полный URL-адрес в заголовке Location, а затем относительные URI в ссылках внутри вашего тела ответа.

+0

Ну, спецификация HTTP для заголовка Location указывает абсолютный URI. Абсолютный URI должен содержать схему (например, http). –

+0

Но вопрос заключается не в том, как построить бесконтекстные непрозрачные * идентификаторы *, он спрашивает, как построить * ссылки *. Последнее может справедливо заключить «в том же сетевом расположении, что и этот документ», и это именно то, что дает пример спецификации заголовка «Местоположение» - абсолютный URI, который не содержит схемы URI или сетевого расположения сервера. Хотя ссылки и идентификаторы часто объединены, они не одно и то же: первый имеет контекст, а второй - нет. –

+0

Можете ли вы отправить ссылку на часть спецификации, о которой вы говорите? –

1

Важным соображением в больших результатах API является дополнительная накладная сеть, включающая полный URI. Верьте или нет, gzip не полностью решает эту проблему (не уверен, почему). Мы были шокированы тем, сколько пространства занял полный URI, когда в результате были включены сотни ссылок.

3

С помощью команды RayLou's trichotomy моя организация opted for favoring (2). Основная причина заключается в том, чтобы избежать атак XSS (Cross-Site Scripting). Проблема в том, что если злоумышленник может вставить свой собственный корневой URL в ответ, возвращаемый с сервера, последующие пользовательские запросы (такие как запрос на аутентификацию с именем пользователя и паролем) могут быть перенаправлены на собственный сервер злоумышленника *.

Некоторые из них подняли вопрос о возможности перенаправления запросов на другие серверы для балансировки нагрузки, но (хотя это не моя область знаний). Я бы сказал, что есть более эффективные способы для выравнивания нагрузки без явного перенаправлять клиентов на разные хосты.

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

+0

Рад, что мой предыдущий ответ был полезен вашей организации. Да, я лично также предпочитаю (2), а.к.... схема без учета абсолютного пути. Однако мне интересно, как вы рассуждаете. Как вы обеспечили соблюдение вашим клиентом только вашего URL-адреса без схемы? Общий клиент, такой как браузер, не будет отклонять URL-адрес без схемы. Поэтому я предполагаю, что вам придется написать свой собственный клиентский код для проверки правильности URL-адресов, прежде чем они будут следовать за ними? Хотя это технически выполнимо (но не обязательно полезно), такая проверка на стороне клиента обычно не является частью обсуждения REST или HATEOAS. – RayLuo

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