Un’analisi del protocollo SOAP e del suo ruolo all’interno dei Web Services.
Il protocollo SOAP (Simple Object Access Protocol) è il cuore dei Web
Services ed è utilizzato come mezzo di scambio d’informazioni XML
tra le varie procedure coinvolte.
Le principali caratteristiche di SOAP sono:
- indipendenza dalla piattaforma
- indipendenza dal linguaggio
- semplicità ed estensibilità
- basato su XML
- abilitazione ad attraversare i firewalls
Tramite SOAP, possiamo inviare messaggi che, grazie ad un formato standard
e tramite la consueta rete Internet/HTTP, consentono di far comunicare le applicazioni
tra loro.
Al momento SOAP non è ancora uno standard, ma è allo stato di
Working Draft 1.2 del W3C (World Wide Web Consortium), dopo che alcuni vendor
(IBM, Microsoft e diversi altri) lo hanno costruito e successivamente donato
al W3C. E’ comunque tuttora attivamente supportato dai produttori di software:
esistono vari toolkit (Apache, IBM, Sun, Microsoft…) che permettono lo
sviluppo rapido di applicazioni SOAP. SOAP è inoltre alla base della
piattaforma Microsoft .NET.
I messaggi SOAP sono essenzialmente dei documenti XML con determinate caratteristiche
(well-formed, utilizzano namespaces, non contengono istruzioni di processing)
e hanno un formato determinato, in cui sono definite le richieste o i risultati
delle elaborazioni.
Un messaggio SOAP prevede, infatti, i seguenti elementi:
- Envelope: l’elemento chiave (root) del documento XML, dove troviamo
informazioni relative alla codifica; - Header: (opzionale) può contenere informazioni descrittive, quali
lingua, data, provenienza, ecc. del messaggio; - Body: la parte principale del messaggio, dove definiamo la richiesta e
la risposta dell’applicazione, tramite dei tag definiti in un nostro
schema (e referenziati nel messaggio con namespaces); - Fault: (opzionale) contiene descrizioni aggiuntive sugli errori che si
possono verificare durante il trasporto del messaggio.
Se, come spesso avviene, il messaggio SOAP viene trasportato tramite http,
in testa a questi elementi occorre aggiungere l’header http, contenente
i ‘metadati’ per trasmettere il messaggio SOAP sottostante.
Riprendendo quanto visto nel capitolo precedente, scriviamo qui sotto un esempio
di messaggio SOAP di richiesta:
POST /InMagazzino HTTP/1.1 Host: www.magazzinopelati.org Content-Type: application/soap+xml; charset=utf-8 Content-Length: nnn <?xml version="1.0"?> |
|||
<soap:Body xmlns:m="http://www.magazzinopelati.org/magazzino"> | |||
<m:RichiestaPrezzo> | |||
<m:NomeProdotto>Pelati</m:NomeProdotto> <m:Quantita>20</m:Quantita> |
|||
</m:RichiestaPrezzo> | |||
</soap:Body> | |||
</soap:Envelope> |
e il corrispettivo messaggio di risposta:
HTTP/1.1 200 OK Content-Type: application/soap; charset=utf-8 Content-Length: nnn <?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> |
|||
<soap:Body xmlns:m="http://www.magazzinopelati.org/magazzino"> | |||
<m:RispostaPrezzo> | |||
<m:Prezzo>3000</m:Prezzo> | |||
</m:RispostaPrezzo> | |||
</soap:Body> | |||
</soap:Envelope> |
Più in dettaglio, vediamo che:
- nell’Envelope, è obbligatorio il riferimento al namespace
xmlns:soap="http://www.w3.org/2001/12/soap-envelope, ed è presente
anche l’indicazione sulla codifica del messaggio; - l’Header non è presente in quanto non obbligatorio: viene
utilizzato per memorizzare informazioni aggiuntive riguardanti il messaggio
(es. login, sessioni…) e soprattutto per tracciarne l’effettiva
consegna. Un attributo importante nell’ Header è il MustUnderstand,
che se settato ad 1, come nel seguente esempio:<SOAP-ENV:header> <trans:Transaction xmlns:trans="some-URI"
SOAP-ENV:mustUnderstand="1">15
</trans:Transaction></SOAP-ENV:header> rende l’elemento obbligatorio per il ricevente. Con l’attributo
Actor possiamo invece definire eventuali server intermedi per la trasmissione
del messaggio e il loro ruolo; - l’elemento Body definisce nel SOAP di richiesta la chiamata alla procedura
e nel SOAP di risposta il risultato. Da notare come i tag che definiscono
queste azioni (richiesta e risposta) sono del tutto personalizzabili secondo
il nostro schema fornito nel namespace, così come del tutto trasparente
è il nostro codice rispetto all’implementazione della procedura
(linguaggio, sistema operativo, ecc.) sul server; - l’elemento Fault non è presente; in esso è possibile
definire messaggi personalizzati di risposta nel caso la richiesta non vada
a buon fine, non producendo quindi il documento XML di risposta (come da esempio).
Un possibile messaggio di Fault per il nostro esempio potrebbe essere:
HTTP/1.1 200 OK Content-Type: application/soap; charset=utf-8 Content-Length: nnn <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding"> |
|||
<soap:Body> | |||
<soap:Fault> | |||
<faultcode>Client</faultcode> <faultstring>Richiesta non Valida</faultstring> |
|||
</soap:Fault> | |||
</soap:Body> | |||
</soap:Envelope> |
in cui si nota che l’elemento Fault è l’unico presente in
Body, e che sono presenti i tag faultcode (codice di ritorno che identifica
chi ha causato la mancata transazione) e faultstring (descrizione estesa dell’errore)
Nel protocollo SOAP sono inoltre presenti ulteriori specifiche, tra cui la
possibilità di interfacciare diversi tipi di dato (semplici, complessi,
arrays…) come parametri delle procedure. Per un dettaglio completo delle
potenzialità di SOAP, rimandiamo al sito del W3C (di SOAP e XML): http://www.w3.org/2000/xp/Group/