Czy mam parsować XML na serwerze, czy podać proxy i pozwolić przeglądarce na parsowanie go?

11

Potrzebuję interfejsu z interfejsem API innej firmy. Za pomocą tego interfejsu API wykonuję żądanie GET w przeglądarce użytkownika końcowego i otrzymuję odpowiedź XML. Dane te mają być wykorzystywane w aplikacji przeglądarkowej, w której użytkownik może je przeszukiwać, podejmować decyzje itp. Głównym problemem jest to, że większość przeglądarek ma zablokowane użycie XML w wielu domenach, więc nie mogę po prostu uzyskać XML z API.

Ogólne dane są jednak zasadniczo podzielone na dwa zestawy.

  1. Pierwszy zestaw danych jest publiczny i musi być co jakiś czas aktualizowany, aby można go było buforować dla wszystkich użytkowników po stronie serwera, znacznie zmniejszając ruch.
  2. Drugi zestaw danych jest prywatny i indywidualny dla każdego użytkownika. Te dane są również częściej aktualizowane w interfejsie API. To powoduje, że buforowanie jest znacznie mniej skuteczne.

Ze względu na skalowalność chciałbym, aby obciążenie serwera było jak najmniejsze.

Przede mną widzą dwie opcje:

  1. Podaj serwer proxy, którego można używać do kierowania żądań XML do serwera innej firmy i bezpośrednio tam iz powrotem między interfejsem API klienta i innej firmy.
  2. Niech serwer dokona konwersji z XML na JSON i usunie niepotrzebne informacje. Zasadniczo oznacza to utworzenie nowego interfejsu API dla naszego serwera, co przekłada się na żądania z zewnętrznego interfejsu API

Jaki byłby najlepszy sposób na dostarczenie danych użytkownikowi? (Nie musi to być jedna z dwóch opcji)

ametystdragon
źródło
Jaki jest związek źródła XML z kodem, który interpretuje go w przeglądarce? Ponieważ jeśli napisałeś własny (nieobsługiwany) kod klienta, aby pobierać dane z niektórych danych podmiotów zewnętrznych, pierwszą rzeczą, o której myślę, jest to, że pewnego dnia ta strona trzecia dokona niewielkiej zmiany w pliku XML i na dobre złamie twoją aplikację.
SJuan76,
Firma zewnętrzna zaktualizowała już swoją wersję interfejsu API. Przez pewien czas utrzymywali starą wersję, umożliwiając użytkownikom aktualizację kodu w celu korzystania z nowego interfejsu API. Struktura danych w XML nie zmieniła się jednak raz zdefiniowana, z wyjątkiem wersji API.
amethystdragon
1
Jeśli interfejs API często się zmienia, prawdopodobnie warto poświęcić czas na zadeklarowanie własnego schematu i posiadanie usługi, która działa jak oprogramowanie pośrednie, zmieniając dane w coś, czego oczekuje klient. Myślę, że pytanie sprowadza się do „Co jest łatwiejsze, aktualizowanie klienta lub aktualizowanie serwera?”
Hiperbola
To nie jest częste. Zmieniło się to raz na 10 lat.
amethystdragon

Odpowiedzi:

12

Opcja proxy jest najłatwiejsza do wdrożenia. Nie musisz wykonywać żadnych niestandardowych prac programistycznych, jedyne, co musisz zrobić, to skonfigurować serwer proxy. Jest to również proste: nie trzeba utrzymywać dodatkowego kodu, a jeśli interfejs API ulegnie zmianie, nie będziesz musiał wprowadzać żadnych zmian.

Serwer proxy byłby preferowanym wyborem:

  • Jeśli potrzebujesz szybko wysłać działające oprogramowanie. To sprawia, że ​​jest to dobry wybór, na przykład, jeśli masz zamiar wysłać funkcję, ale na etapie wdrażania projektu odkryłeś, że nie możesz po prostu wysyłać żądań AJAX między domenami.

  • Lub jeśli obecny interfejs API jest dobrze zaprojektowany : architektura jest dobra, wywołania są bardzo jasne, dokumentacja jest kompletna i łatwa do zrozumienia.

  • Lub jeśli obecny interfejs API może ulec zmianie. Jeśli to się zmieni, wystarczy zmienić implementację JavaScript. Jeśli zamiast proxy analizujesz wyniki i generujesz własny JSON, istnieje ryzyko, że zmiany w interfejsie API będą wymagać zmian w kodzie serwera.

Z drugiej strony, parsowanie wyniku ma tę zaletę, że umożliwia całkowite wyodrębnienie interfejsu API po stronie klienta. Jest to wolniejsza alternatywa, ponieważ wymaga zaprojektowania nowego interfejsu (jeśli oryginalny interfejs API nie jest dobrze zaprojektowany) i wdrożenia funkcji wyodrębniania, przekształcania i ładowania, ale może być dobrym długoterminowym wyborem dla dużego projektu. To jest preferowany wybór:

  • Jeśli potrzebujesz dodatkowych funkcji. Możesz wykorzystać różne funkcje, które nie były dostępne w oryginalnym interfejsie API, takie jak buforowanie na poziomie, który nie jest obsługiwany przez zwykły serwer proxy, szyfrowanie lub inny model uwierzytelniania .

    Na przykład, jeśli liczba żądań AJAX stanie się problemem lub jeśli dwukierunkowy model komunikacji ma sens, możesz zaimplementować gniazda sieciowe.

  • Lub jeśli obecny interfejs API nie jest dobrze zaprojektowany. To podejście, podobnie jak wzór elewacji, umożliwia przeprojektowanie interfejsu API. Jeśli oryginalny jest kiepski, posiadanie fasady umożliwia rozwiązanie złych wyborów projektowych dokonanych przez pierwotnych autorów starszego API. Możesz działać również na dużych częściach, takich jak ogólna architektura interfejsu API, ale także na szczegółach, takich jak nazwy argumentów lub komunikaty o błędach.

    Chociaż modyfikacja istniejącego API jest czasami niemożliwa, posiadanie fasady może umożliwić pracę z kawałkiem czystego kodu, który wyodrębnia wady i błędy w oryginalnym projekcie.

  • Lub jeśli obecny interfejs API może ulec zmianie. Rzeczywiście, możesz zmienić kod po stronie serwera zamiast JavaScript, jeśli API zmienia się w czasie, jednocześnie nie zmieniając publicznego interfejsu fasady. Może to być łatwiejsze, ponieważ masz większe doświadczenie w programowaniu po stronie serwera lub znasz więcej narzędzi do refaktoryzacji po stronie serwera lub dlatego, że w projekcie łatwiej jest radzić sobie z wersjonowaniem kodu po stronie serwera.

Możesz zauważyć, że pominąłem mówienie o JSON, wydajności, buforowaniu itp. Jest tego powód:

  • JSON vs. XML: wybór odpowiedniej technologii zależy od Ciebie . Robisz to, mierząc obiektywnie przegrzanie XML-a przez JSON, czas potrzebny do serializacji danych i łatwość parsowania.

  • Wydajność: porównuj różne wdrożenia, wybierz najszybszą, a następnie profiluj ją i optymalizuj na podstawie wyników z profilera. Zatrzymaj się po osiągnięciu wydajności określonej w wymaganiach niefunkcjonalnych.

    Zrozum także, co próbujesz osiągnąć. Istnieje kilka części współdziałających ze sobą: oryginalny interfejs API, przepustowość między serwerem a interfejsem API, wydajność serwera, przepustowość między serwerem a użytkownikami końcowymi oraz wydajność ich maszyn. Jeśli zostaniesz poproszony o uzyskanie odpowiedzi na żądanie w ciągu 30 ms., Ale oryginalny interfejs API wyda 40 ms. przetworzenie żądania, bez względu na to, co robisz, nie będziesz w stanie uzyskać wymaganej wydajności.

  • Buforowanie: buforowanie to jedna z technik przyspieszania działania aplikacji internetowej, zmniejszania przepustowości itp.

    1. Upewnij się, że używasz również buforowania klienta (buforowanie po stronie serwera nie zmniejszy wykorzystania przepustowości między tobą a klientami), biorąc pod uwagę, że prawidłowe skonfigurowanie nagłówków HTTP jest często trudne.

    2. Upewnij się, że poprawnie określiłeś, co chcesz buforować, na jak długo i kiedy go unieważnić: jeśli opis produktu zmienił się 10 sekund temu, ale klienci strony internetowej handlu elektronicznego nadal widzą starą wersję, to jest OK. Jeśli właściciel zmienił opis, przesłał go i nadal widzi poprzedni wariant z powodu buforowania, jest to problematyczne.

    3. Nie skupiaj się tylko na buforowaniu. Ważna jest również na przykład minimalizacja. Korzystne może być również zmniejszenie liczby żądań.

Arseni Mourzenko
źródło
1
+1 wahałem się trochę, czy powinienem wspomnieć o buforowaniu i ostatecznie zdecydowałem się tego nie robić. Wciąż warto o tym mówić, dobra uwaga.
JensG
7

Istnieje trzecia opcja, której być może nie widziałeś: Udostępnianie zasobów pochodzących z różnych źródeł (CORS) .

Standard CORS działa poprzez dodanie nowych nagłówków HTTP, które pozwalają serwerom obsługiwać zasoby w dozwolonych domenach źródłowych. Przeglądarki obsługują te nagłówki i przestrzegają ustanowionych ograniczeń.

Przykład : Załóżmy, że Twoja witryna to http://my-cool-site.com i masz interfejs API strony trzeciej w domenie http://third-party-site.com , do którego możesz uzyskać dostęp za pośrednictwem AJAX.

Załóżmy, że strona, którą serwujesz z my-cool-site.com, wysłała prośbę do strony trzeciej-partia.com. Zwykle przeglądarka użytkowników odrzuca połączenia AJAX z dowolną witryną inną niż Twoja domena / subdomena zgodnie z Zasadami bezpieczeństwa tego samego pochodzenia . Ale jeśli przeglądarka i serwer innej firmy obsługują CORS, zdarzają się następujące rzeczy:

  • Przeglądarka wyśle ​​następujący nagłówek HTTP na stronę trzecia strona.com

    Origin: http://my-cool-site.com
  • Jeśli serwer innej firmy zaakceptuje żądania z Twojej domeny, odpowie następującym nagłówkiem HTTP:

    Access-Control-Allow-Origin: http://my-cool-site.com
  • Aby zezwolić na wszystkie domeny, serwer innej firmy może wysłać ten nagłówek:

    Access-Control-Allow-Origin: *
  • Jeśli Twoja witryna nie jest dozwolona, ​​przeglądarka zgłosi błąd.

Jeśli klient ma dość nowoczesne przeglądarki, które obsługują CORS , a twój serwer innej firmy również obsługuje CORS , możesz na pewno przejść na to z drobnymi zmianami w kodzie.

Znalazłem fajne wyjaśnienie na temat CORS , na którym znajdziesz także inny sposób: JSONP . Ale JSONP wymagałby sporo zmian w kodzie.

Aby złożyć wniosek CORS, wystarczy użyć XMLHttpRequestw Firefoksie 3.5+, Safari 4+ i Chrome i XDomainRequestsprzeciwić się w IE8 +. Podczas używania XMLHttpRequestobiektu, jeśli przeglądarka zobaczy, że próbujesz wysłać żądanie między domenami, płynnie wyzwoli zachowanie CORS.

Oto funkcja javascript, która pomaga utworzyć obiekt CORS dla różnych przeglądarek.

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;
}

Ponieważ mówisz, że „większość przeglądarek zablokowała użycie XML w wielu domenach”, domyślam się, że twój serwer zewnętrzny może nie obsługiwać CORS. Następnie musisz znaleźć alternatywne podejście.


sampathsris
źródło
1
Czy możesz spróbować podsumować treść linków? Linki są podatne na gnicie linków i dlatego nie są najlepszym sposobem przekazywania informacji na temat SE :)
Am
Niestety serwer innej firmy nie obsługuje CORS.
amethystdragon
4

Ze względu na skalowalność chciałbym, aby obciążenie serwera było jak najmniejsze

Myślę, że to mniej więcej wskazuje na odpowiedź. To, czy dostarczamy wstępnie przetworzone dane klientowi, zależy od:

  1. różnica w odniesieniu do ruchu
  2. wpływ przetwarzania na wydajność
  3. wpływ innego formatu danych na klienta

Jeśli kod XML jest porównywalnie mały lub jest tylko kilka żądań, sensowne może być przekazanie go klientowi i zapomnienie. To samo dotyczy sytuacji, gdy wstępnie przetworzone dane nadal stanowią dużą część oryginalnych danych lub jeśli klient nie jest w stanie wiele zyskać na innym formacie danych (na przykład JSON).

Jeśli jednak klient ma problemy z przetwarzaniem dużego zestawu danych XML lub jeśli potrzebuje tylko niewielkiej części oryginalnych danych XML, wówczas może być sensowne przeprowadzenie wstępnego przetwarzania po stronie serwera.

Na koniec łatwiej jest skalować serwer, niż skalować klienta / przeglądarkę lub dostępną przepustowość. Mówiąc w jednym zdaniu, zależy to od tego, gdzie jest wąskie gardło w systemie.

JensG
źródło
+1 i dodawanie - przetestuj wydajność w różnych sytuacjach.
SeraM,
0

Moim wyborem byłoby buforowanie i kompresowanie (wyrzucanie niepotrzebnych informacji) i gzip wyników do przeglądarki klienta, twoja opcja # 2 . Ponieważ przeglądarki nie są zwykle wysokiej klasy procesorami, a linie sieciowe między serwerami a przeglądarkami mają ograniczoną pojemność. Mówię o klientach mobilnych . Jeśli nie planujesz obsługiwać klientów mobilnych, wybierz coś prostszego, np. NiektóreGoogle:CORS proxy

xmojmr
źródło