Protokół SOAP
10 lutego 2009
W każdym systemie rozproszonym, niezależnie od tego czy jest to CORBA, DCOM, .NET Remoting czy cokolwiek innego, niezbędny jest pewny protokół zdalnego wywoływania kodu. Java posiada swój RMI, CORBA - GIOP/IIOP, DCOM - własny protokół, ponadto w Uniksach często stosuje się RPC firmy Sun Microsystems. Ten ostatni próbowano pogodzić z językiem XML i w rezultacie stworzono XML-RPC, zwany protokołem XML pierwszej generacji. Jego następcą jest niewątpliwie jeden z ciekawszych protokołów zdalnego wywoływania procedur (i nie tylko) - SOAP.
Podstawowe założenia
SOAP zakłada, że każda wiadomość jest wysyłana od konkretnego nadawcy do przynajmniej jednego odbiorcy przy opcjonalnym udziale jednego lub więcej pośredników. Każdy z elementów uczestniczących w przekazaniu wiadomości (tj. nadawca, pośrednik i odbiorca) jest nazywany węzłem i posiada swój własny adres URI. Dodatkowo, każda przesyłana wiadomość jest całkowicie niezależna od pozostałych, a protokół nie wspiera żadnych mechanizmów synchronizacji.
Budowa wiadomości
Każda wiadomość składa się z nagłówka (header) i ciała (body). Pierwszy z tych elementów może być analizowany przez każdego z pośredników, a także przez ostatecznych odbiorców. Ciało wiadomości jest zarezerwowane jedynie dla odbiorców. Poniżej przedstawiono strukturę wiadomości:
<?xml version="1.0"?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:m="http://www.example.org/timeouts" xmlns:xml="http://www.w3.org/XML/1998/namespace"> <env:Header> ... </env:Header> <env:Body> ... <env:Fault> ... </env:Fault> </env:Body> </env:Envelope>
Nagłówek jest podzielony na bloki. Każdy blok posiada informację o roli do której jest przeznaczony, informacje czy musi być analizowany przez węzeł, informacje dotyczące warunków w których ma on być przekazany dalej oraz właściwe dane. Nagłówki służą głownie do realizacji przez pośredników dodatkowych zadań takich jak autoryzacja, logowanie czy dodatkowe mechanizmy bezpieczeństwa. Nagłówki są opcjonalne.
Ciało wiadomości jest częścią wymaganą przez standard, mimo że jej zawartość jest praktycznie dowolna. To właśnie w tym miejscu umieszczana jest treść wiadomości. Jedyną istotną rzeczą jest env:Fault jest to opcjonalny element używany do przekazywania informacji o błędach.
Cechy (features)
Niezwykle istotnym elementem protokołu SOAP są cechy (features), opisują one w dokładny sposób niemalże każdy aspekt całego procesu zdalnego wywołania procedury. Implementacje mają tutaj dość dużą dowolność, dzięki czemu mogą nadać pożądane w danym przypadku dodatkowe właściwości, które pozwolą lepiej wykorzystać możliwości protokołu SOAP.
Role (roles)
Role opisują zachowanie węzła po otrzymaniu danej wiadomości. Każdy blok w nagłówku posiada informację do jakiej roli jest przeznaczony, co decyduje czy węzeł powinien analizować zawartość danego bloku. Podobnie jak węzły i cechy, role także posiadają swój adres URI, który służy do ich identyfikacji. Wersja 1.2 standardu SOAP definiuje trzy role, lecz możliwe jest wprowadzenie dodatkowych.
- next - każdy pośrednik oraz odbiorca musi przeanalizować nagłówek wiadomości
- none - nagłówek wiadomości nie może być analizowany
- ultimateReceiver - nagłówek wiadomości jest analizowany jedynie przez ostatecznych odbiorców, jest to domyślna rola
Właściwości (properties)
Kolejnym istotnym elementem protokołu SOAP są właściwości. Przechowują one istotne informacje dotyczące wiadomości nie będące jednak jej częścią. Najczęściej dotyczą one szczegółów związanych z transmisją danych. Podobnie jak większość innych elementów SOAP właściwości także identyfikowane są adresami URI.
Istnieją dwa konteksty właściwości: kontekst węzła (environment context) i kontekst wiadomości (message exchange context). Pierwszy zawiera informacje dotyczące konkretnego węzła, takie jak jego numer IP czy lokalną datę i czas. Drugi oprócz standardowego opisu wiadomości takiego jak jej ID zawieta także informacje zależne od konkretnego MEP-a.
Wzorce wymiany wiadomości (MEP)
MEP jest wzorcem według którego węzły SOAP wymieniają miedzy sobą informację. Każdy wzorzec tego typu posiada swój własny adres URI. Ich implementacja jest ściśle zależna od rodzaju wykorzystywanego protokołu niższej warstwy. Dodatkowo w zależności od schematu wg którego przesyłane są dane transmisja jest podzielona na poszczególne etapy. Dwa schematy wymienione w standardzie (które muszą być implementowane przez obsługę HTTP) to Response Message Exchange Pattern i Request-Response Message Exchange Pattern. Zasadnicza różnica między nimi jest taka, że pierwszy schemat nie zakłada przesyłania szczegółowego żądania. Ogranicza się ono do prostego wywołania zależnego od używanego protokołu niższej warstwy (np. HTTP). W obu przypadkach odpowiedź jest pełnowartościową wiadomością SOAP.
Przetwarzanie wiadomości
Po otrzymaniu wiadomości każdy węzeł analizuje ją w poszukiwaniu informacji, które są dla niego przeznaczone. Wygląda to w następujący sposób.
- Nagłówek wiadomości jest przeszukiwany pod kątem istnienia bloków przeznaczonych do roli jaką spełnia węzeł.
- Odnajdywane są bloki nagłówka obowiązkowe do przetworzenia.
- Jeżeli węzeł nie jest w stanie przetworzyć któregokolwiek z bloków znalezionych w powyższych punktach wysyłana jest zwrotna informacja o błędzie.
- W przeciwnym wypadku węzeł przetwarza w odpowiedni dla siebie sposób znalezione bloki. Jeżeli jest jednocześnie ostatecznym odbiorcą przetwarza także ciało wiadomości.
- W sytuacji gdy węzeł nie jest odbiorcą oraz nie wystąpił żaden błąd wiadomość jest przekazywana dalej z pominięciem przetworzonych bloków w nagłówku.
Transmisja wiadomości
W większości przypadków SOAP wykorzystuje do przesyłania danych protokół HTTP. Dzięki temu łatwiej jest zbudować system oparty na SOAP w sieci z firewallami i serwerami proxy. Warto także zauważyć, że HTTP idealnie odpowiada specyfice SOAP. Każda wiadomość SOAP, podobnie jak każde żądanie HTTP, jest całkowicie niezależna od pozostałych. Naturalnie, możliwe jest także wykorzystywanie HTTPS do transmisji wymagających większego bezpieczeństwa. Inną alternatywą, choć dość rzadko spotykaną i omawianą, jest wykorzystanie protokołu SMTP. Spotyka się także implementacje które dla zwiększenia wydajności operują bezpośrednio na niższej warstwie - protokole TCP.
Jak zostało to wspomniane w paragrafie o wzorcach wymiany wiadomości, transmisja jest podzielona na stany. Oto przykładowy przebieg transmisji Request-Response Message Exchange Pattern z użyciem protokołu HTTP.
- init
Odpowiednia właściwość kontekstu wiadomości zawiera adres HTTP węzła do którego należy się połączyć. Wykorzystywana jest w zależności od konfiguracji i/lub implementacji metoda GET lub POST. W żądaniu HTTP umieszczone zostają wszystkie informacje dotyczące kodowania znaków. W tym czasie nasłuchujący adresat przyjmuje połączenie i jeżeli nie wystąpi żaden błąd oczekuje na zakończenie transmisji ze strony nadawcy. - requesting
Używając metody określonej w poprzednim etapie przesyłana jest treść żądania do adresata. W zależności od odpowiedzi algorytm może powrócić do stanu init aby ponowić próbę (ma to miejsce np. przy przekierowaniach), fail jeżeli wystąpił bład lub sending+receiving jeżeli wszystko przebiegło pomyślnie. W tym samym czasie adresat jest w stanie responding w którym oczekuje na dane od nadawcy i po ich odebraniu wysyła odpowiedź. - sending+receiving
W tym stanie adresat przetwarza otrzymaną wiadomość. Transmisja danych jest zakończona. - success lub fail
W zależności od wyniku przeprowadzonej operacji węzeł kończy przesyłanie danych z informacją o sukcesie lub porażce.
Serializacja danych
Niezbędnym elementem w każdym systemie zdalnych wywołań procedur jest mechanizm serializacji przekazywanych danych, takich jak argumenty funkcji. Nazwy występujące w programie wykorzystującym SOAP są modyfikowane w taki sposób aby mogły zostać użyte w każdym elemencie języka XML. Dlatego niedozwolone znaki zastępuje się ich wartością szestnastkową w UTF-16 (lub UTF-8) dla przykładu Hello world zostanie zamienione na Hello_x0020_world.
Wywołanie jest przedstawiane w ciele wiadomości jako element o nazwie takiej jak nazwa funkcji (oczywiście po zakodowaniu znaków niedozwolonych w XML-u) zawierający wszystkie wejściowe i wejściowo-wyjściowe argumenty. Każdy argument jest przedstawiany jako element o tej samej nazwie zawierający jego wartość (także po przekształceniu w formę akceptowalną dla XML-a). Odpowiedzią jest element o dowolnej nazwie zawierający wszystkie argumenty wyjściowe oraz wejściowo-wyjściowe. Sposób ich zapisu jest taki sam jak w przypadku wywołania. Do RPC wykorzystywane są wzorce Response Message Exchange Pattern i Request-Response Message Exchange Pattern, chociaż standard zezwala także na inne.
Zastosowanie
SOAP jest jednym z elementów pozwalającym na rozproszoną dystrybucję komponentów. Razem z technologiami takimi jak WSDL pozwala on na stworzenie rozbudowanego systemu podobnego do CORBA i DCOM. W rezultacie zostało to uczynione w Java 2 Enterprise Edition (gdzie SOAP występuje obok Java RMI) oraz platformie .NET, gdzie SOAP ma za zadanie całkowicie wyprzeć DCOM. Często też spotyka się tę technologię w aplikacjach webowych z racji wykorzystania typowych dla tej dziedziny technologii jak XML i HTTP. Trwają także prace nad standardem XUP, który jest czymś w rodzaju połaczenia SOAP i XUL. Zakłada on wykorzystanie SOAP do przekazywania informacji o zdarzeniach dotyczących interfejsu opartego na XML (na przykład wspomniany XUL).
Podsumowanie
SOAP jest niewątpliwie ciekawym protokołem, mimo że oparcie się na XML-u ogranicza jego wydajność. Co prawda trwają pracę nad technologiami takimi jak Binary XML, który pozwolą przyśpieszyć pracę z XML-em, lecz jak na razie w starciu wydajnościowym CORBA czy DCOM bez problemu są w stanie pokonać SOAP.
To co jest wadą jest także i zaletą, fakt, że SOAP opiera się na XML-u pozwala na wykorzystanie w nim wielu istniejących już technologii (chociażby XSLT czy algorytmy serializacji danych). Stawia on na modułowość i łatwość dostępu co niejednokrotnie jest ważniejsze od wydajności. Jednak niezależnie od tego, jest to bez wątpienia bardzo interesująca technologia.
Komentarze do wpisu "Protokół SOAP" zablokowane.
1.
xyz napisał(a):
11 lutego 2009, 12:54:07
Trzeba dodać jeden z najbardziej znienawidzonych, skomplikowanych, generujących multum problemów (zwłaszcza przy komunikazji między różnymi implementecjami) itd.
2.
Nowaker napisał(a):
11 lutego 2009, 13:23:53
Skomplikowanych, ale ustandaryzowanych. Różne implementacje to nie wina standardu, lecz osób implementujących.
3.
Paweł Dziepak napisał(a):
11 lutego 2009, 16:16:13
@xyz: rzeczywiście specyfikacja SOAP nie wyczerpuje tematu komunikacji między różnymi implementacjami. Z drugiej strony dzięki temu pozostawiono dużą swobodę, która pozwoliła na wykorzystanie tego protokołu w różnych zastosowaniach. Jest to coś kosztem czegoś, standard nie jest restrykcyjny, ale pojawiają się problemy z kompatybilnością różnych implementacji. Taka jest po prostu specyfika tego protokołu.