ugrás a tartalomhoz

SOAP: Együttműködés távoli szolgáltatásokkal

Anonymous · 2004. Szep. 7. (K), 21.00
SOAP: Együttműködés távoli szolgáltatásokkal
Néhány hete jelent meg - a Kiskapu gondozásában magyar fordításban is elérhető - Advanced PHP Programming című könyv távoli szolgáltatások használatával foglalkozó fejezetének első része webhelyünkön. A PHP fejlesztés felsőfokon címen megjelent könyv ezen fejezete a SOAP technológia ismertetésével folytatódik, rátérve a WSDL praktikáira, majd végül összehasonlítja az XML-RPC és SOAP megoldásokat.

SOAP

A sorozatban megjelent

A SOAP eredetileg a Simple Object Access Protocol (egyszerű objektumelérési protokoll) rövidítése volt, de az 1.1-es változattól önállósult. A SOAP egy olyan protokoll, amely alkalmas változatos környezetbeli adatcserék lebonyolítására. Az XML-RPC-től eltérően, ami kifejezetten az RPC-k kezelésére hivatott, a SOAP általános üzenetkezelésre készült, így az RPC-k ügye csak egyike a számos alkalmazásának. Mindazonáltal, fejezetünk az RPC-kről szól, így most csak a SOAP 1.1 hozzájuk kapcsolódó részéről szólunk.

Hogy is néz ki a SOAP? Íme egy SOAP boríték, amely az xmethods.net tőzsdei árfolyam- lekérdező SOAP szolgáltatását alkalmazza a hivatalos bemutató példa megvalósítására, vagyis az IBM tőzsdei árfolyamának lekérdezésére (azért hivatalos , mert ez a példa szerepel a SOAP bemutató leírásában):

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"
  soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <soap:Body>
    <getQuote xmlns="http://www.themindelectric.com/wsdl/net.xmethods.services.stockquote.StockQuote/">
      <symbol xsi:type="xsd:string">ibm</symbol>
    </getQuote>
  </soap:Body>
</soap:Envelope>
Íme a válasz:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
  xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
  soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <soap:Body>
    <n:getQuoteResponse xmlns:n="urn:xmethods-delayed-quotes">
      <Result xsi:type="xsd:float">90.25</Result>
    </n:getQuoteResponse>
  </soap:Body>
</soap:Envelope>
A SOAP esete jól példázza azt, hogy egy egyszerű elgondolás nem feltétlenül jár együtt egyszerű megvalósítással. A SOAP üzenet egy borítékból áll, ami egy fejlécet és egy üzenettörzset tartalmaz. Minden elem névtereken található, ami nagyszerű gondolat, de nehézkessé teszi az XML olvasását.

A legkülső címke neve Envelope - ez tartalmazza magát a SOAP üzenetet. Ez az elem az xmlsoap névtérben található, amit teljes minősített nevéből (<soap:Envelope>) és e névtér meghatározásából is láthatunk:

xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
Ez kapcsolatot teremt a soap és az alábbi névtér-URI között:
http://schemas.xmlsoap.org/soap/envelope/

A SOAP és a Schema

A SOAP belső működéseihez igénybe veszi a Schema segítségét, ami egy XML alapú nyelv adatszerkezetek meghatározására és ellenőrzésére. A közmegegyezés szerint egy elem teljes névtere (például http://schemas.xmlsoap.org/soap/envelope/) egy, a névteret leíró Schema dokumentum. Ez a meghatározás azonban nem kötelező érvényű - a névtérnek még csak URL-nek sem kell lennie -, de a teljesség kedvéért ezt alkalmazzák.

A névterek ugyanazt a szerepet töltik be az XML-ben, amit más programozási nyelvekben: Segítenek elkerülni az ütközéseket két megvalósítás neve között. Vegyük a legfelső szintű címkét (<soap-env:Envelope>). Az Envelope tulajdonságnév eszerint a soap-env névtérben található. Így hát, ha a FedEX valamilyen okból egy XML formátumot határoz meg, amely az Envelope tulajdonságot használja, ezt nyugodtan megteheti a teljes <FedEX:Envelope> névvel, és semmi baj nem történik.

A SOAP Envelope-on belül négy névtér létezik:
  • xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" - A SOAP boríték Schema meghatározása leírja az alapvető SOAP objektumokat - ez a névtér szerepel minden SOAP kérelemben.
  • xmlns:xsi="http://www.w3.org/21/XMLSchema-instance" - Az xsi:type elemtulajdonság gyakran használatos az elemek típusának megadásánál.
  • xmlns:xsd="http://www.w3.org/21/XMLSchema" - A Schema megad néhány alapvető adattípust, melyeket adataink meghatározásánál és az ellenőrzésnél használhatunk.
  • xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding" - Ez a típuskódolások meghatározása, melyek a szabványos SOAP kérelmekben megjelennek.
A <GetQuote> elem szintén egy névtérben található - ez esetben egy meglehetősen hosszú nevűben:
http://www.themindelectric.com/wsdl/net.xmethods.services.stockquote.StockQuote
Figyeljük meg a Schema használatát a tőzsdei azonosító típusmeghatározásában és elrendezésében:

<symbol xsi:type="xsd:string">ibm</symbol>
A <symbol> karakterlánc típusú.

Hasonlóan, a válaszban is látható az árfolyam típusának meghatározása:

<Result xsi:type="xsd:float">90.25</Result>
Itt láthatjuk, hogy az eredmény egy lebegőpontos szám. Mindez hasznunkra lehet, hiszen a Schema érvényességi eszközeivel ellenőrizhetjük dokumentumunkat. Így például, ha a válasz a következő alakban érkezik, érvénytelennek tekintik, mivel a foo nem érvényes lebegőpontos szám:

<Result xsi:type="xsd:float">foo</Result>

WSDL

A SOAP méltó párja a WSDL (Web Services Description Language - webszolgáltatás-leíró nyelv). Ez egy XML alapú nyelv, ami kifejezetten arra szolgál, hogy a webszolgáltatások (leggyakrabban a SOAP) lehetőségeit és tagfüggvényeit leírjuk. Íme egy WSDL fájl, amely a korábban már alkalmazott tőzsdei szolgáltatás leírását adja:

<?xml version="1.0" encoding="UTF-8" ?>
<definitions name="net.xmethods.services.stockquote.StockQuote"
  targetNamespace= "http://www.themindelectric.com/wsdl/net.xmethods.services.stockquote.   StockQuote/"
  xmlns:tns= "http://www.themindelectric.com/wsdl/net.xmethods.services.stockquote.   StockQuote/"
  xmlns:electric="http://www.themindelectric.com/"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/">
  <message name="getQuoteResponse1">
    <part name="Result" type="xsd:float" />
  </message>
  <message name="getQuoteRequest1">
    <part name="symbol" type="xsd:string" />
  </message>
  <portType name="net.xmethods.services.stockquote.StockQuotePortType">
    <operation name="getQuote" parameterOrder="symbol">
      <input message="tns:getQuoteRequest1" />
      <output message="tns:getQuoteResponse1" />
    </operation>
  </portType>
  <binding name="net.xmethods.services.stockquote.StockQuoteBinding"
    type="tns:net.xmethods.services.stockquote.StockQuotePortType">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
    <operation name="getQuote">
      <soap:operation soapAction="urn:xmethods-delayed-quotes#getQuote" />
      <input>
        <soap:body use="encoded" namespace="urn:xmethods-delayed-quotes"
          encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
      </input>
      <output>
        <soap:body use="encoded" namespace="urn:xmethods-delayed-quotes"
          encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
      </output>
    </operation>
  </binding>
  <service name="net.xmethods.services.stockquote.StockQuoteService">
    <documentation>
      net.xmethods.services.stockquote.StockQuote web service
    </documentation>
    <port name="net.xmethods.services.stockquote.StockQuotePort"
      binding="tns:net.xmethods.services.stockquote.StockQuoteBinding">
      <soap:address location="http://66.28.98.121:9090/soap" />
    </port>
  </service>
</definitions>
Látható, hogy a WSDL sem takarékoskodik a névterek használatával, szerkezete pedig kissé felrúgni látszik a logika szabályait.

A kód első vizsgálatra érdemes része a <portType> címke, amely meghatározza a végrehajtható műveleteket, valamint a ki- és bevitt üzeneteket. Esetünkben a getQuote műveletet adja meg, amely a getQuoteRequest1 kérelmet fogadja, és a getQuoteResponse1 választ adja vissza.

A getQuoteResponse1 <message> címkéi szerint tartalma egyetlen, float típusú Result elem. Hasonlóképpen, a getQuoteRequest1 egyetlen string típusú symbol elemet tartalmaz.

Következik a <binding> címke. A <portType>-hoz a type tulajdonságon keresztül kapcsolódik egy kötés, amely megegyezik a <portType> nevével. A kötések a protokoll és az adatátvitel tulajdonságait határozzák meg (például a SOAP üzenet törzsében elhelyezett adatok kódolását), de a címeket nem. Egy kötés egyetlen protokollhoz tartozhat - esetünkben a HTTP-hez, kapcsolatukat az alábbi kód adja meg:

<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
Végezetül, a <service> címke felsorol néhány kaput, és címeket határoz meg számukra. Mivel esetünkben csak egyetlen kaput használunk, a következő kóddal hivatkozunk rá és kötjük a http://66.28.98.121:9090/soap címhez:

<port name="net.xmethods.services.stockquote.StockQuotePort"
  binding="tns:net.xmethods.services.stockquote.StockQuoteBinding">
  <soap:address location="http://66.28.98.121:9090/soap" />
</port>
Érdemes megjegyeznünk, hogy semmi sem köti a SOAP-ot a HTTP protokollhoz, és választ sem kell feltétlenül visszaadnia. Ez egy rugalmas, általános célú protokoll, melynek a HTTP felett működő RPC csak egyik megvalósítása. A WSDL fájl arról tájékoztat, hogy milyen szolgáltatások érhetők el, és ezt hogyan és hogyan férhetünk hozzájuk. A kérelmet és a választ ezután a SOAP valósítja meg.

Szerencsére a PEAR SOAP osztályai elvégzik a munka nagyobb részét. Egy SOAP kérelem kiadásához először egy új SOAP_Client ügyfélobjektumot kell készítenünk, és át kell adnunk a WSDL fájlt az elérni kívánt szolgáltatásokkal. A SOAP_Client ezután elkészíti az összes szükséges helyettes kódot a közvetlenül végrehajtott kérelmekhez, legalábbis olyan esetekben, amikor az adatok mind egyszerű Schema típusoknak feleltethetők meg. Az alábbiakban bemutatunk egy teljes ügyfélkérelmet az xmethods.net tőzsdei szolgáltatásához:

<?php
require_once "SOAP/Client.php";
$url = "http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl";
$soapclient = new SOAP_Client($url, true);
$price = $soapclient->getQuote("ibm")->deserializeBody();
print "Current price of IBM is $price\n";
?>
A SOAP_Client ezután átvállalja a helyettes objektum készítésének terhét, mellyel közvetlenül futtathatjuk a WSDL-ben megadott tagfüggvényeket. A getQuote() hívását követően a rendszer kicsomagolja az eredményt, és a PHP saját típusaiba írja a deserializeBody() segítségével. A futtatáskor az alábbi eredményt kapjuk:

> php delayed-stockquote.php
Current price of IBM is 90.25

A sysem.load átírása SOAP szolgáltatássá

SOAP programozói tudásunkat nyomban próbára is tehetjük - kíséreljük meg SOAP alatt megvalósítani az XML-RPC sysem.load szolgáltatását.

Először is, SOAP szolgáltatásunkat a SOAP_Service különleges célú változataként kell megvalósítanunk. Ehhez legalább az alábbi négy függvény megvalósítására szükség van:
  • public static function getSOAPServiceNamespace(){} - Vissza kell adnunk az általunk meghatározott szolgáltatás névterét.
  • public static function getSOAPServiceName(){} - Vissza kell adnunk szolgáltatásunk nevét.
  • public static function getSOAPServiceDescription(){} - Vissza kell adnunk szolgáltatásunk leírását egy karakterlánc alakjában.
  • public static function getWSDLURI(){} - Vissza kell adnunk a szolgáltatást leíró WSDL fájl URL-jét.
Ezeken felül természetesen meg kell határoznunk saját tagfüggvényeinket is.

Íme az új SOAP SystemLoad megvalósítás osztályának meghatározása:

<?php 
require_once 'SOAP/Server.php';

class ServerHandler_SystemLoad implements SOAP_Service {
  public static function getSOAPServiceNamespace()
    { return 'http://example.org/SystemLoad/'; }
  public static function getSOAPServiceName()
    { return 'SystemLoadService'; }
  public static function getSOAPServiceDescription()
    { return 'Return the one-minute load avergae.'; }
  public static function getWSDLURI()
    { return 'http://localhost/soap/tests/SystemLoad.wsdl'; }
  
  public function SystemLoad()
  {
    $uptime = `uptime`;
    if(preg_match("/load averages?: ([\d.]+)/", $uptime, $matches)) {
      return array( 'Load' => $matches[1]);
    }
  }
}
?>
Az XML-RPC-től eltérően a SOAP_Service tagfüggvények paramétereiket hagyományos PHP változók alakjában kapják meg. Visszatéréskor mindössze a válaszüzenet patamétereinek tömbjét kell megadnunk. A névterek választásánál szabad kezet kapunk, de a rendszer ellenőrzi azokat a megadott WSDL fájl alapján, így egymással összhangban kell legyenek.

Ha meghatároztunk egy szolgáltatást, az XML-RPC-hez hasonlóan be kell jegyeztetnünk. A következő példában készítünk egy új SOAP_Server objektumot, csatoljuk az új szolgáltatást, és utasítjuk a kiszolgálópéldányt a bejövő kérelmek kezelésére:

<?php
$server = new SOAP_Server;
$service = new ServerHandler_System_Load;
$server->addService($service);
$server->service('php://input');
?>
Van tehát egy teljes értékű kiszolgálónk, de nincs még meg a WSDL fájl, melyből az ügyfelek megtudhatnák, hogyan férhetnek hozzá ehhez a kiszolgálóhoz. Ennek elkészítése nem nehéz feladat - csak sok időbe telik. Lássuk, milyen eredményre számíthatunk:

<?xml version='1.0' encoding='UTF-8'?>
<definitions name='SystemLoad'
  targetNamespace='http://example.org/SystemLoad/'
  xmlns:tns='http://example.org/SystemLoad/'
  xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
  xmlns:xsd='http://www.w3.org/2001/XMLSchema'
  xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
  xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
  xmlns='http://schemas.xmlsoap.org/wsdl/'>
  <message name='SystemLoadResponse'>
    <part name='Load' type='xsd:float'/>
  </message>
  <message name='SystemLoadRequest'/>
  <portType name='SystemLoadPortType'>
    <operation name='SystemLoad'>
      <input message='tns:SystemLoadRequest'/>
      <output message='tns:SystemLoadResponse'/>
    </operation>
  </portType>
  <binding name='SystemLoadBinding' type='tns:SystemLoadPortType'>
    <soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/>
    <operation name='SystemLoad'>
      <soap:operation soapAction='http://example.org/SystemLoad/'/>
      <input>
        <soap:body use='encoded'
          namespace='http://example.org/SystemLoad/'
          encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
      </input>
      <output>
        <soap:body use='encoded'
          namespace='http://example.org/SystemLoad/'
          encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
      </output>
    </operation>
  </binding>
  <service name='SystemLoadService'>
    <documentation>System Load web service</documentation>
    <port name='SystemLoadPort' binding='tns:SystemLoadBinding'>
      <soap:address location='http://localhost/soap/tests/SystemLoad.php'/>
    </port>
  </service>
</definitions>
Nos, itt nem sok újdonság bukkant fel. Figyeljük meg, hogy a névterek egybecsengenek azzal, amit a ServerHandler_SystemLoad-nál láthattunk, továbbá a SystemLoad prototípusa szerint egy Load nevű lebegőpontos számmal tér vissza.

A szolgáltatáshoz tartozó ügyfél hasonlít a tőzsdés példában látotthoz:

<?php
include("SOAP/Client.php");
$url = "http://localhost/soap/tests/SystemLoad.wsdl";
$soapclient = new SOAP_Client($url, true);
$load = $soapclient->SystemLoad()->deserializeBody();
print "One minute system load is $load\n";
?>

Amazon webszolgáltatások és összetett típusok

A SOAP egyik legnagyobb előnye az XML-RPC-vel szemben, hogy támogatja a felhasználók által meghatározott típusokat, melyeket a Schema segítségével készíthetnek el és ellenőrizhetnek. A PEAR SOAP-megvalósítása pedig képes automatikusan átírni e saját változókat a PHP típusaira.

Mindennek bemutatására lássuk, miként kereshetünk meg egy szerzőt az Amazon.com webszolgáltatási API-jával. Az Amazon nagy hangsúlyt fektet webszolgáltatásainak megfelelő működésére, és elérhetővé teszi minden keresési lehetőségét a SOAP-on keresztül. Az Amazon API használatához fejlesztőként kell bejegyeztetnünk magunkat az Amazon webhelyén, a http://www.amazon.com/gp/aws/landing.html címen. Ha belepillantunk az Amazon WSDL fájljába, láthatjuk, hogy a szerző keresésének művelete az alábbi blokkban található (http://soap.amazon.com/schemas2/Amazon-WebServices.wsdl):

<operation name="AuthorSearchRequest">
  <input message="typens:AuthorSearchRequest" />
  <output message="typens:AuthorSearchResponse" />
</operation>
A kimeneti és bemeneti üzenetek típusát itt az alábbiak szerint határozzák meg:

<message name="AuthorSearchRequest">
  <part name="AuthorSearchRequest" type="typens:AuthorRequest" />
</message>
és

<message name="AuthorSearchResponse">
  <part name="return" type="typens:ProductInfo" />
</message>
Mindkettő saját, a Schema-ban meghatározott típus. Íme az AuthorRequest típusos meghatározása:

<xsd:complexType name="AuthorRequest">
  <xsd:all>
    <xsd:element name="author" type="xsd:string" />
    <xsd:element name="page" type="xsd:string" />
    <xsd:element name="mode" type="xsd:string" />
    <xsd:element name="tag" type="xsd:string" />
    <xsd:element name="type" type="xsd:string" />
    <xsd:element name="devtag" type="xsd:string" />
    <xsd:element name="sort" type="xsd:string" minOccurs="0" />
    <xsd:element name="variations" type="xsd:string" minOccurs="0" />
    <xsd:element name="locale" type="xsd:string" minOccurs="0" />
  </xsd:all>
</xsd:complexType>
Ahhoz, hogy ezt a típust PHP-ben is megjeleníthessük, készítenünk kell egy erre a célra szolgáló osztályt, amely a SchemaTypeInfo felületet is megvalósítja. Ehhez két műveletet kell megírnunk:
  • public static function getTypeName() {} - Visszaadja a típus nevét.
  • public static function getTypeNamespace() {} - Visszaadja a típus névterét.
Esetünkben az osztály egyszerűen a tulajdonságok tárolójaként viselkedik. Mivel ezek a Schema alaptípusai, nincs szükség további erőfeszítésre.

Lássuk tehát az AuthorRequest burkolóosztályát:

<?php
class AuthorRequest implements SchemaTypeInfo {
  public $author;
  public $page;
  public $mode;
  public $tag;
  public $type;
  public $devtag;
  public $sort;
  public $variations;
  public $locale;
  
  public static function getTypeName()
    { return 'AuthorRequest';}
  public static function getTypeNamespace()
    { return 'http://soap.amazon.com';}
}
A szerző szerinti keresés megvalósításához először készítenünk kell egy SOAP_Client helyettes objektumot az Amazon WSDL fájlból:

<?php
require_once 'SOAP/Client.php';
$url = 'http://soap.amazon.com/schemas2/AmazonWebServices.wsdl';
$client = new SOAP_Client($url, true);
?>
Ezután hozzunk létre egy AuthorRequest objektumot, és töltsük fel a keresés adataival:

<?php
$authreq = new AuthorRequest;
$authreq->author = 'schlossnagle';
$authreq->mode = 'books';
$authreq->type = 'lite';
$authreq->devtag = 'DEVTAG';
?>
Az eredményt a ProductInfo típusban kapjuk vissza, ami túlzottan összetett ahhoz, hogy a felépítésével itt foglalkozzunk. Mindazonáltal az alábbi rövid kóddal gyorsan utánajárhatunk, mely könyvek szerzőit hívták Schlossnagle-nek:

<?php
$result = $client->AuthorSearchRequest($authreq)->deserializeBody();
foreach ($result->Details as $detail) {
  print "Title: $detail->ProductName, ASIN: $detail->Asin\n";
}
?>
Futtatása után az alábbi eredményt kapjuk:

Title: Advanced PHP Programming, ASIN: 0672325616

Helyettes kód készítése

Nem nehéz feladat olyan kódot írni, ami dinamikusan elkészíti a helyettes (proxy) objektumokat a WSDL-ből, de ez a folyamat meglehetősen sok értelmezési munkával jár, amit jobb elkerülni, különösen, ha egy webszolgáltatást gyakran hívnak. A SOAP WSDLkezelője képes elkészíteni a PHP kódot, így közvetlenül is lebonyolíthatjuk a hívásokat, anélkül, hogy újra és újra át kellene vizsgálni a WSDL fájlt.

A helyettes kód elkészítésének érdekében töltsük be az URL-t az MSDLManager::get() tagfüggvénnyel, és hívjuk meg a generateProxyCode() függvényt. Mindezt most a SystemLoad WSDL fájl példáján mutatjuk be:

<?php
require_once 'SOAP/WSDL.php';
$url = "http://localhost/soap/tests/SystemLoad.wsdl";
$result = WSDLManager::get($url);
print $result->generateProxyCode();
?>
A futtatás után az alábbi kódhoz jutunk:

<?php
class WebService_SystemLoadService_SystemLoadPort extends SOAP_Client {
  public function __construct()
  {
    parent::_ _construct("http://localhost/soap/tests/SystemLoad.php", 0);
  }
  function SystemLoad()
  {
    return $this->call("SystemLoad",
                       $v = array(),
                 array('namespace'=>'http://example.org/SystemLoad/',
                       'soapaction'=>'http://example.org/SystemLoad/',
                       'style'=>'rpc',
                       'use'=>'encoded' ));
  }
}

Mostantól a WSDL fájl értelmezése helyett közvetlenül ezt az osztályt hívhatjuk.

A SOAP és az XML-RPC összehasonlítása

Melyik RPC protokollt alkalmazzuk - a SOAP vagy az XML-RPC mellett tegyük le voksunkat? Nos, sok esetben a körülmények nem hagynak túlzottan nagy mozgásteret. Ha olyan szolgáltatást valósítunk meg, ami meglevő ügyfelekkel vagy kiszolgálókkal érintkezik, elvesztjük a döntés lehetőségét. Így a SOAP felület használata webnaplónkban érdekes kísérlet lehet, de valószínűleg nem képes együttműködni más, már eleve meglevő eszközökkel. Ha az Amazon vagy a Google API-jaival szeretnénk együttműködni, ismét csak egyértelmű a válasz: a SOAP-ot kell használnunk.

Ha azonban új szolgáltatást telepítünk, és szabad kezet kapunk a választásban, az alábbiakat érdemes megfontolnunk:
  • A megvalósítás szemszögéből nézve az XML-RPC sokkal kevesebb kezdeti erőfeszítést igényel, mint a SOAP.
  • Az XML-RPC kisebb dokumentumokat készít, melyek értelmezése kevésbé költséges, mint a SOAP-pal készítetteké.
  • A SOAP lehetővé teszi a Schema segítségével meghatározott saját típusok használatát. Ez módot ad az adatok érvényességének hatékonyabb ellenőrzésére, valamint az automatikus típusátalakításra az XML és a PHP között. Az XML-RPC-ben mindenféle összetettebb adatcsomagolást kézzel kell elvégeznünk.
  • A WSDL nagyszerű eszköz. A SOAP automatikus felderítési és helyetteskód-készítési képességei jobbak az XML-RPC-ben elérhetőknél.
  • A SOAP jelentős támogatást kap az IBM-től, a Microsofttól, valamint számos, a sikerében érdekelt internetes vállalattól. Mindez azt jelenti, hogy e cégek a múltban és a jövőben is jelentős anyagi erőforrásokat és időt szentelnek arra, hogy javítsák a SOAP együttműködési készségét és a SOAP-hoz kötődő segédeszközöket fejlesszenek.
  • A SOAP általános, bővíthető eszköz, míg az XML-RPC célirányos protokoll, viszonylag merev meghatározással.
Az XML-RPC-t vonzóan egyszerű megoldásnak tartom olyankor, amikor a megvalósítandó RPC mindkét oldala felett befolyásom van. Ilyen esetekben a helyes automatikus felderítés és a helyettes kód készítésének hiánya nem okoz fejfájást. Ha azonban olyan szolgáltatást telepítek, melyet mások is támogatnak, mindenképpen a SOAP választását tartom jobbnak széleskörű támogatottsága és hatékony segédeszközei miatt.

További olvasmányok

A távoli szolgáltatásokkal való együttműködés témaköre igen széles, sokkal szélesebb annál, mint amennyit e fejezet átfogni képes. A SOAP különösen érdekes, fejlődő szabvány; maga is megérdemelne egy külön könyvet. A következőkben néhány hasznos forrásmunkát mutatunk be, témakörök szerint csoportosítva.

SOAP

A SOAP leírása megtalálható a http://www.w3.org/TR/SOAP/ címen.

A http://www.soapware.org/bdg nagyszerű bevezetést ad a SOAP használatába.

Shane Caraveo webszolgáltatásokról adott előadásainak anyaga a http://talks.php.net címen segít megérteni, mi szükséges a SOAP sikeres használatához a PHP-ben. Jó tudnunk, hogy Shane a PHP 5 SOAP-megvalósításának vezető fejlesztője.

XML-RPC

Az XML-RPC leírása megtalálható a http://www.xmlrpc.com/spec címen.

Dave Winer, az XML-RPC megalkotója egy kellemes bevezető írását a következő címen lelhetjük meg: http://davenet.scripting.com/1998/07/14/xmlRpcForNewbies.

Webnaplózás

A Blogger API leírását a http://www.blogger.com/developers/api/1_docs címen találhatjuk meg.

A MetaWeblog API leírása a http://www.xmlrpc.com/metaWeblogApi címen található.

A MovableType bővítményeket kínál mind a MetaWeblog, mind a Blogger API-hez. Leírásuk a http://www.movabletype.org/docs/mtmanual_programmatic.html címen megtalálható.

Az RSS egy nyílt XML formátum tartalom-közzétételhez. Leírását a http://blogs.law.harvard.edu/tech/rss címen lelhetjük meg.

Az XML-RPC példáinkban szereplő Serendipity webnaplózó rendszer a http://www.s9y.org címen érhető el.

Nyilvánosan elérhető webszolgáltatások

A http://xmethods.net kifejezetten a webszolgáltatások fejlesztéséhez (elsősorban a SOAP és a WSDL alkalmazásokhoz) nyújt segítséget. Itt ingyenesen elérhető webszolgáltatások garmadáját találhatjuk, a szerkesztők pedig az együttműködési képességek próbára tételére hívnak fel.

Az Amazon rendelkezik egy szabad SOAP felülettel. A részletekről a http://www.amazon.com/gp/aws/landing.html címen érdeklődhetünk.

A Google is rendelkezik szabad SOAP keresőfelülettel. Erről a http://www.google.com/apis címen olvashatunk.

Zárszó

Kétrészes sorozatunk a PHP fejlesztés felsőfokon című könyvből ezennel végetért. Aki kíváncsi a folytatásra, illetve a könyv más érdekes tippjeire, az mindenképpen látogasson el egy közeli könyvesboltba, és lapozzon bele a könyvbe élőben is.