Должен ли я анализировать XML на сервере или предоставить прокси и позволить браузеру анализировать его?


11

Мне нужно интерфейс со сторонним API. С помощью этого API я делаю GET-запрос из браузера конечного пользователя и получаю XML-ответ. Эти данные должны использоваться в браузерном приложении, где пользователь может выполнять поиск по ним, использовать их для принятия решений и т. Д. Основная проблема заключается в том, что большинство браузеров заблокировали междоменное использование XML, поэтому я не могу просто получить XML из API.

Общие данные, тем не менее, в основном разбиты на два набора.

  1. Первый набор данных является общедоступным, и его нужно обновлять только так часто, чтобы его можно было кэшировать для всех пользователей на стороне сервера, что значительно снижает трафик.
  2. Второй набор данных является частным и индивидуальным для каждого пользователя. Эти данные также обновляются в API чаще. Это приводит к тому, что кэширование становится гораздо менее эффективным.

Из соображений масштабируемости я хотел бы сохранить нагрузку на сервер как можно меньше.

Я вижу перед собой два варианта:

  1. Предоставьте прокси-сервер, который можно использовать для маршрутизации XML-запросов на сторонний сервер и напрямую между клиентом и сторонним API.
  2. Попросите сервер выполнить преобразование из XML в JSON и удалить ненужную информацию. По сути, это означает создание нового API для нашего сервера, который транслируется в запросы от стороннего API

Каков наилучший способ предоставления данных пользователю? (Не обязательно должен быть один из двух вариантов)


Какова связь источника XML с кодом, который интерпретирует его в браузере? Потому что, если вы написали свой собственный (неподдерживаемый) код клиента для подачи из сторонних данных, первое, о чем я думаю, это то, что однажды третья сторона внесет небольшие изменения в XML и навсегда сломает ваше приложение.
SJuan76

Сторонние разработчики обновили свою версию API уже один раз. Они немного сохранили старую версию, позволяя людям обновлять свой код для использования нового API. Однако структура данных в XML не изменилась после определения, кроме как между версиями API.
аметистдрагон

1
Если API часто меняется, вероятно, стоит потратить время на объявление собственной схемы и создание службы, которая выполняет роль промежуточного программного обеспечения, манипулируя данными в соответствии с ожиданиями вашего клиента. Я думаю, что вопрос сводится к «Что проще, обновить клиента или обновить сервер?»
Гипербола

Это не часто. Он менялся один раз за 10 лет.
amethystdragon

Ответы:


12

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

Прокси будет предпочтительным выбором:

  • Если вам нужно быстро отправить работающее программное обеспечение. Это делает его хорошим выбором, например, если вы собирались отправить функцию, но обнаружили, что на этапе реализации проекта вы не можете просто делать междоменные запросы AJAX.

  • Или, если текущий API хорошо спроектирован : архитектура хорошая, вызовы очень четкие, документация полная и понятная.

  • Или если текущий API может быть изменен. Если он меняется, вам просто нужно изменить реализацию JavaScript. Если вместо прокси-сервера вы анализируете результаты и генерируете свой собственный JSON, существует риск того, что изменения в API потребуют изменений в вашем коде на стороне сервера.

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

  • Если вам нужны дополнительные функции. Вы можете использовать различные функции, которые не были доступны в исходном API, такие как кэширование на уровне, который не поддерживается обычным прокси-сервером, или шифрование , или другая модель аутентификации .

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

  • Или, если текущий API не очень хорошо разработан. Подобно шаблону фасада, этот подход позволяет вам перепроектировать API. Если исходный является плохим, наличие фасада позволяет решить неправильные дизайнерские решения, сделанные первоначальными авторами устаревшего API. Вы можете действовать как с большими частями, такими как общая архитектура API, так и с деталями, такими как имена аргументов или сообщения об ошибках.

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

  • Или если текущий API может быть изменен. В самом деле, вы можете предпочесть изменить код на стороне сервера вместо JavaScript, если API изменяется со временем, не затрагивая общедоступный интерфейс вашего фасада. Это может быть проще либо потому, что вы более опытны в программировании на стороне сервера, либо потому, что вы знаете больше инструментов для рефакторинга на стороне сервера, либо потому, что в вашем проекте проще работать с версиями кода на стороне сервера.

Вы можете заметить, что я пропустил разговор о JSON, производительности, кэшировании и т. Д. Есть причина для этого:

  • JSON vs. XML: вам нужно выбрать правильную технологию. Вы делаете это путем объективного измерения перегрева XML по сравнению с JSON, времени, необходимого для сериализации данных, и простоты синтаксического анализа.

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

    Также поймите, чего вы пытаетесь достичь. Есть несколько частей, взаимодействующих друг с другом: исходный API, пропускная способность между вашим сервером и API, производительность вашего сервера, пропускная способность между вашим сервером и конечными пользователями и производительность их компьютеров. Если вас просят получить ответ на запрос в течение 30 мс, но оригинальный API тратит 40 мс. обрабатывая запрос, независимо от того, что вы делаете, вы не сможете получить требуемую производительность.

  • Кэширование. Кэширование - это один из методов ускорения работы веб-приложения, снижения пропускной способности и т. Д.

    1. Убедитесь, что вы также используете клиентское кэширование (кэширование на стороне сервера не уменьшит использование полосы пропускания между вами и клиентами), учитывая, что правильная настройка заголовков HTTP часто бывает сложной задачей.

    2. Убедитесь, что вы правильно определили, что кэшировать, как долго и когда его аннулировать: если описание продукта изменилось 10 секунд назад, но клиенты веб-сайта электронной коммерции по-прежнему видят старую версию, это нормально. Если владелец изменил описание, отправил его и все еще видит предыдущий вариант из-за кеширования, это проблематично.

    3. Не зацикливайтесь только на кешировании. Минимизация, например, также важна. Сокращение количества запросов также может быть полезным.


1
+1 Я немного поколебался о том, стоит ли мне упоминать о кешировании, и, наконец, решил против этого. Все еще стоит поднять это, хорошая мысль.
JensG

7

Существует третий вариант, который вы, возможно, не видели: перекрестное совместное использование ресурсов (CORS) .

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

Пример : скажем, ваш сайт http://my-cool-site.com и у вас есть сторонний API на домене http://third-party-site.com , к которому вы можете получить доступ через AJAX.

И давайте предположим, что страница, которую вы сервер с my-cool-site.com сделал запрос на third-party-site.com. Обычно браузер пользователей отклоняет вызовы AJAX на любой другой сайт, кроме вашего собственного домена / субдомена в соответствии с Политикой безопасности того же источника . Но если браузер и сторонний сервер поддерживают CORS, происходит следующее:

  • Браузер отправит следующий HTTP-заголовок на third-party-site.com

    Origin: http://my-cool-site.com
  • Если сторонний сервер принимает запросы от вашего домена, он ответит следующим HTTP-заголовком:

    Access-Control-Allow-Origin: http://my-cool-site.com
  • Чтобы разрешить все домены, сторонний сервер может отправить этот заголовок:

    Access-Control-Allow-Origin: *
  • Если ваш сайт не разрешен, браузер выдаст ошибку.

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

Я нашел хорошее объяснение по CORS , на котором вы также найдете другой способ сделать это: JSONP . Но JSONP потребует изрядного количества изменений в вашем коде.

Чтобы сделать запрос CORS, вы просто используете XMLHttpRequestв Firefox 3.5+, Safari 4+ и Chrome и XDomainRequestобъект в IE8 +. При использовании XMLHttpRequestобъекта, если браузер увидит, что вы пытаетесь сделать междоменный запрос, он будет беспрепятственно запускать поведение CORS.

Вот функция JavaScript, которая помогает вам создавать кросс-браузерный объект CORS.

function createCORSRequest(method, url){
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr){
        // XHR has 'withCredentials' property only if it supports CORS
        xhr.open(method, url, true);
    } else if (typeof XDomainRequest != "undefined"){ // if IE use XDR
        xhr = new XDomainRequest();
        xhr.open(method, url);
    } else {
        xhr = null;
    }
    return xhr;
}

Поскольку вы говорите, что «большинство браузеров заблокировали междоменное использование XML», я думаю, ваш сторонний сервер может не поддерживать CORS. Тогда вы должны найти альтернативные подходы.



1
Не могли бы вы попытаться обобщить содержание в ссылках? Ссылки склонны к гниению ссылок, и поэтому это не лучший способ передать информацию о SE :)
Ampt

К сожалению, сторонний сервер не поддерживает CORS.
amethystdragon

4

Из соображений масштабируемости я хотел бы сохранить нагрузку на сервер как можно меньше

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

  1. разница в отношении трафика
  2. влияние на производительность обработки
  3. влияние другого формата данных на клиента

Если XML сравнительно невелик или имеется только несколько запросов, может иметь смысл просто переслать его клиенту и забыть о нем. То же самое верно, когда предварительно обработанные данные все еще составляют большую часть исходных данных, или если клиент не может извлечь большую выгоду из другого формата данных (например, JSON).

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

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


+1, а добавление - проверить работоспособность в разных ситуациях.
SeraM

0

Мой выбор - кэшировать и сжимать (выбрасывать ненужную информацию) и отправлять результаты gzip в браузер клиента, ваш вариант №2 . Поскольку браузеры обычно не являются высокопроизводительными процессорами, а сетевые линии от сервера к браузеру имеют ограниченную емкость. Я говорю о мобильных клиентах . Если вы не планируете поддерживать мобильные клиенты, выберите что-нибудь попроще, например, некоторыеGoogle:CORS proxy

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.