%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% :SOAP
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{SOAP} \label{SOAP}

SOAP (Simple Object Access Protocol) je v~současnosti nejrozšířenější protokol používaný pro RPC webové služby. Definuje jakým způsobem volat metody webové služby, jak těmto metodám zadat parametry i~jak bude vrácena případná návratová hodnota. Komunikace se, podobně jako v~HTTP, skládá z~požadavku a~odpovědi. Odpověď je zaslána vždy, a~to i~v případě volání metody bez návratové hodnoty. V~takovém případě slouží jako kontrola, že požadavek na server dorazil a~byl vyřízen. Jako formát pro požadavky a~odpovědi bylo zvoleno XML, které se dá efektivně a~jednoznačně programově zpracovat.



\subsection{SOAP požadavek}

SOAP požadavek je XML dokument skládající se ze dvou částí -- SOAP obálky a~popisu volané webové metody. SOAP obálka má předdefinovanou XML gramatiku a~slouží jako identifikátor pro server. Všechny elementy obálky se nachází ve jmenném prostoru \texttt{http://schemas.xmlsoap.org/soap/envelope/}. Kořenový element má název \texttt{Envelope} a~obsahuje jeden dceřiný element s~názvem \texttt{Body}. Následující příklad ukazuje, jak vypadá prázdná SOAP obálka.

\begin{Verbatim}
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP:Body>
  </SOAP:Body>
</SOAP:Envelope>
\end{Verbatim}


\fcolorbox{boxout}{boxin}{
\parbox{0.98\linewidth}{
Zvláště ve starších materiálech jako je například \cite{Web Services Essentials} se můžeme setkat ještě s~jedním elementem obálky --- \texttt{Header}. V~něm byly nastaveny doplňující informace jako způsob kódování, činitel ap. Časem se ale od standardních parametrů hlavičky upustilo, jelikož nebyly používány. Dnes některé webové služby používají hlavičku na transport vlastních parametrů, v~této publikaci se jimi ale nebudeme zabývat.
}}



\subsection{Volání webové metody}

Volaná webová metoda je v~SOAPu reprezentována XML elementem. Tento element má jméno volané metody a~je přímým potomkem elementu \texttt{Body}. Obvykle je každá webová metoda přiřazena do nějakého jmenného prostoru, nesmíme proto zapomenout zde tento jmenný prostor specifikovat. V~následující příkladu voláme webovou metodu s~názvem \texttt{withdraw}, která náleží do prostoru jmen \texttt{piggybank}.

\begin{Verbatim}
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP:Body>
    \codeHighlight{<piggy:withdraw xmlns:piggy="piggybank">}
    \codeHighlight{</piggy:withdraw>}
  </SOAP:Body>
</SOAP:Envelope>
\end{Verbatim}




\subsection{Parametry webové metody}

Parametry webové metody jsou reprezentovány jako XML elementy. Každý z~nich má stejné jméno jako parametr a~je přímým potomkem elementu reprezentujícího webovou metodu. Hodnota parametru je vyjádřena hodnotou příslušného XML elementu. Webové parametry musí následovat ve stejném pořadí, v~jakém jsou deklarovány v~dokumentaci volané webové metody (resp. ve WSDL souboru). Webové parametry obvykle nepatří do žádného prostoru jmen. V~příkladu doplníme volanou metodu o~parametr \texttt{amount} s~hodnotou \texttt{100.0}.

\begin{Verbatim}
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP:Body>
    <piggy:withdraw xmlns:piggy="piggybank">
      \codeHighlight{<amount>100.0</amount>}
    </piggy:withdraw>
  </SOAP:Body>
</SOAP:Envelope>
\end{Verbatim}




\subsection{Koncové body}

SOAP webová služba se skládá z~tzv. koncových bodů (endpoints). Koncový bod je abstraktní útvar, který má přidělenou vlastní URL a~obsahuje nějaké webové metody. V~podstatě se jedná o~modularizaci webové služby do menších částí a~roztřídění poskytovaných metod podle funkčnosti. Princip je stejný jako v~objektově orientovaném programování -- každý objekt (v~našem případě koncový bod) by měl mít svou vlastní zodpovědnost a~řešit nějaký konkrétní problém. 



\subsection{Zaslání na server}

Vyplněnou SOAP obálku musíme nějakým způsobem doručit na server. Nejčastěji používaným způsobem je protokol HTTP, kde SOAP obálka je přiložena v~těle POST metody (podrobnosti o~HTTP a~metodě POST byly popsány v~kapitole \ref{HTTP}) a~zaslána na URL nějakého koncového bodu. Server pak vrátí SOAP odpověď přiloženou v~těle HTTP odpovědi \texttt{200 OK}. MIME typ pro SOAP obsah je podle W3C stanoven na \texttt{application/soap+xml}, někdy se však používá pouze \texttt{application/xml}.

\begin{Verbatim}
POST /account HTTP/1.1
Host: www.piggybank.com
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 260
Authorization: Basic cGVwYTp6ZGVwYQ==

<?xml version="1.0" encoding="utf-8"?>
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP:Body>
    <piggy:withdraw xmlns:piggy="piggybank">
      <amount>100.0</amount>
    </piggy:withdraw>
  </SOAP:Body>
</SOAP:Envelope>

\end{Verbatim}




\subsection{Zaslání přes SMTP}

Někdy očekáváme, že vyřízení SOAP požadavku zabere větší čas. Pak se může hodit poslat jej pomocí protokolu SMTP (protokol používaný pro e-maily, není součástí této publikace). Ten neočekává odpověď okamžitě. Následující příklad ukazuje zprávu posílanou protokolem SMTP. Hlavní část zprávy se od předchozího způsobu neliší. Nezávislost na transportu je jednou z~velkých výhod protokolu SOAP. 

\begin{Verbatim}
To: <service@soap.piggybank.com>
From: <pepa@soap.piggybank.com>
Date: Tue, 2 Mar 2010 15:46:00 +0100
MIME-Version: 1.0
Content-Type: application/soap+xml; charset=utf-8

<?xml version="1.0" encoding="utf-8"?>
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP:Body>
    <piggy:withdraw xmlns:piggy="piggybank">
      <amount>100.0</amount>
    </piggy:withdraw>
  </SOAP:Body>
</SOAP:Envelope>

\end{Verbatim}




\subsection{SOAP odpověď}

Na každý SOAP požadavek musí přijít klientovi SOAP odpověď. Nejdůležitější je to u~webových metod, které vrací hodnotu. Struktura SOAP odpovědi je podobná jako u~požadavku. Obsahuje stejné elementy \texttt{Envelope} a~\texttt{Body}. Jako potomek elementu \texttt{Body} je uvedena návratová hodnota (pokud existuje, jinak je tento element prázdný). Přitom zde může, ale nemusí jít o~přímého potomka. Záleží na návrhu webové služby. Někteří programátoři preferují obalit návratovou hodnotu do elementu, který vypovídá o~jménu volané metody. To je obzvlášť důležité u~posílání SOAP požadavků přes protokol SMTP, jelikož odpovědi nám pak přijdou asynchronně a~bez obalovacího elementu bychom nemuseli zjistit, která odpověď se vztahuje ke kterému požadavku. Přesnou strukturu návratové hodnoty vyčtete z~dokumentace webové služby. V~následujícím příkladu server jako odpověď na požadavek o~vybrání peněz z~účtu v~Piggy Bank vrátil zůstatek po výběru (\texttt{balance}). Pro jasnější identifikaci je tato hodnota obalena do elementu \texttt{withdrawResponse} z~jmenného prostoru \texttt{piggybank}.

\begin{Verbatim}
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 250

<?xml version="1.0" encoding="utf-8"?>
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP:Body>
    <piggy:withdrawResponse xmlns:piggy="piggybank">
      <balance>8900.00</balance>
    </piggy:withdrawResponse>
  </SOAP:Body>
</SOAP:Envelope>

\end{Verbatim}




\subsection{Chyba jako korektní SOAP odpověď}

Chybová hláška je v~SOAPu považována za naprosto korektní odpověď. Pokud dojde na serveru ve webové službě k~běhové výjimce, vrátí server (při používání HTTP) odpověď \texttt{200 OK} s~popisem chyby. Ten je součástí XML elementu \texttt{Fault} ležícím ve jmenném prostoru SOAPu. Element \texttt{Fault} je přímým potomkem elementu \texttt{Body}. Předpokládejme, že klient chtěl vybrat ze svého účtu v~Piggy Bank více peněz, než kolik měl. Následující příklad ukazuje chybovou hlášku, kterou mu server vrátil.

\begin{Verbatim}
HTTP/1.1 200 OK
Content-Type: application/soap+xml
Content-Length: 323

<?xml version="1.0" encoding="utf-8"?>
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP:Body>
    <SOAP:Fault>
      <faultcode>Client</faultcode>
      <faultstring>Not enough money</faultstring>
      <faultactor>netukar.piggybank.soap.Account</faultactor>
    </SOAP:Fault>
  </SOAP:Body>
</SOAP:Envelope>

\end{Verbatim}

Element \texttt{Fault} obsahuje tři dceřiné elementy. První z~nich, \texttt{faultcode}, má hodnotu \texttt{Client} (hodnota je určena specifikací) a~říká, že chyba vznikla na straně klienta. Alternativou by byla hodnota \texttt{Server} pro chybu na straně serveru. Dalším je element \texttt{faultstring} obsahující lidsky čitelný popis chyby (určený například pro zalogování). Posledním je element \texttt{faultactor} s~popisem kde chyba vznikla. Framework JAX-WS, který si představíme později, tuto hodnotu vyplňuje plně kvantifikovaným názvem třídy, ve které chyba vznikla. Všimněte si též, že všechny tyto tři elementy mají názvy začínající malým písmenem a~neleží v~žádném jmenném prostoru (chovají se tedy jako parametry).




\subsection{Typy parametrů a~návratových hodnot}

Jelikož je SOAP pouze předdefinovanou XML gramatikou, používá stejné datové typy pro hodnoty elementů jako XML Schema. Nejčastěji používané základní typy jsou celé číslo, desetinné číslo a~řetězec. Datový typ datum a~čas je popsán v~\cite{XML Schema Date/Time}. Postup, jak převést instanci třídy v~Javě na XML element je popsán v~kapitole \ref{XML Objects}, stejně jako datový typ pole. U~programování klienta pro SOAP webovou službu máme k~dispozici dvojici WSDL dokument spolu s~XML Schematem webové služby, proto nám XML parser zajistí nejen deserializaci případného objektu v~odpovědi, ale i~kontrolu datových typů. Pamatujte na to, že nejsnadněji se v~případě SOAPu pracuje s~JavaBeany.




\subsection{Styl zprávy RPC a~DOCUMENT} \label{SOAP Style and Use}

SOAP umožňuje v~současnosti dva styly zprávy. Jsou to RPC a~DOCUMENT. Styl RPC používáme v~celé této publikaci -- XML element obalující parametry volané webové metody má stejný název jako volaná webová metoda. Silnou stránkou stylu RPC je snadná čitelnost jak pro programátora, tak pro servlet zpracovávající SOAP požadavky. Nevýhodou stylu RPC může být, že SOAP požadavek obecně nejde snadno validovat. Zatímco název metody a~názvy parametrů jsou obsaženy ve WSDL souboru, struktura parametrů (pokud se jedná o~pole nebo objekty) je obsažena v~XML Schematu.

Druhou možností je styl DOCUMENT, kde parametry webové metody obaleny nejsou. Ztrácí se tak možnost rozeznat, kterou metodu voláme (pokud jich má daný koncový bod více a~nějaké mají stejný počet parametrů). Výhodou je, že můžeme snadno SOAP požadavek validovat oproti XML Schematu. V~\cite{Enterprise JavaBeans 3.0} zmíněné omezení řeší tak, že webová metoda bere pouze jeden parametr typu objekt, který je pojmenovaný podobně jako metoda (řeší problém s~identifikací) a~schovává v~sobě pravé parametry metody jakožto své atributy.





\subsection{Použití zprávy LITERAL a~ENCODED}

Použití (use) LITERAL, které jsme používali doposud, znamená, že hodnoty XML elementů nemají výslovně uveden žádný typ. Kromě něho existuje alternativní možnost ENCODED. Potom jsou všechny parametry kvantifikovány svým typem podle XML Schematu (tedy z~parametru \texttt{<amount>100</amount>} se stane \texttt{<amount type="xsd:int">100</amount>}. U~webových služeb se přetížené metody nepoužívají, na serveru se tedy snadno pozná, jestli jsme poslali parametry správných typů nebo ne (pokud ne, JVM na serveru ohlásí chybu). U~odpovědi stejně musíme podle dokumentace a~WSDL souboru vědět, co nám server pošle, jinak by naše klientská aplikace neměla smysl. Použití ENCODED se tak dnes už téměř nepoužívá, lze se s~ním ale setkat v~materiálech staršího data, např. v~\cite{Web Services Essentials}.

Tato publikace používá kombinaci RPC/LITERAL jelikož je snadno pochopitelná a~čitelná. Velmi oblíbenou je však i~kombinace DOCUMENT/LITERAL. Pokud vás styly a~použití SOAP zpráv zajímá více, článek \cite{SOAP Styles and Uses} diskutuje u~obou těchto  kombinací jejich výhody a~nevýhody spolu s~ukázkami SOAP požadavků a~WSDL souboru.





\subsection{Závěr}

SOAP je v~současnosti nejrozšířenější protokol pro webové služby typu RPC. Díky jeho založení na XML se jak odchozí tak příchozí zprávy snadno zpracovávají. Ve svém vývoji dosáhl řady zjednodušení takže je ve finální podobě snadno čitelný a~pochopitelný. Má také velkou podporu v~knihovnách jazyka Java, ale i~v~jiných programovacích jazycích. Mezi jeho další výhody patří nezávislost na transportním protokolu. Při návrhu RPC webové služby využívající SOAP je třeba klást důraz na dobrou modularizaci metod  v~koncových bodech a~také na správný návrh metod. Vyhnete se tím hlavním problémům, které jsou SOAPu vytýkány mimo jiné také v~\ref{RESTful Web Services}.



Použitá literatura:\\
\cite{Enterprise JavaBeans 3.0} \emph{Enterprise JavaBeans 3.0 -- Kapitoly 18 a~19}\\
\cite{Web Services Essentials} \emph{Web Services Essentials}\\
\cite{SOAP Wikipedia} \emph{SOAP na Wikipedii}\\
\cite{SOAP Specifications} \emph{Specifikace SOAP}\\

