Thursday, May 14, 2009

SOAP web service with Zend Framework

SOAP web service with Zend Framework

SOAP definition from Wikipedia:

SOAP is a protocol for exchanging XML-based messages over computer networks, normally using HTTP/HTTPS.

I was surprised that Zend Framework (1.5), at the time of writing, still has no component for SOAP. Actually such component exists, but it’s still in incubator, so if you want to use it, you have to get current Zend Framework version from SVN (svn checkout http://framework.zend.com/svn/framework/trunk) or to download the latest snapshot.

What I really needed was WSDL generator because standard PHP SOAP extension does not support WSDL generation.

Zend_Soap component has a very handy helper, Zend_Soap_AutoDiscover, which will generate WSDL file using PHPDoc (PHP has no static typing, so API docs are the only way to get the required info, this accomplished using reflection functionality of PHP).

Note: At the time of writing Zend_Soap_AutoDiscover fails to create a valid WSDL if the methods of your object have default parameters. So make sure you don’t have them… If you must have them, you can use Zend_Soap_Wsdl to manually create WSDL. Edit: this issue is now fixed.

To use Zend_Soap_AutoDiscover you have to document all params, their types and return types. Lets say, we want a service to log some messages. For actual logging we have a class called Writer, which has a write method, that just writes given string to a file (the params are described in PHPDoc):



  1. class Writer {

  2. private static $fileName = 'message.txt';

  3. /**
  4. * Write to a file
  5. *
  6. * @param string $string
  7. * @return boolean
  8. */
  9. public function write($string) {
  10. try {
  11. $file = new File(self::$fileName);
  12. $file->lock();
  13. $result = $file->write($string);
  14. $file->unlock();
  15. $file->close();
  16. return $result;
  17. } catch (Exception $e) {
  18. return false;
  19. }
  20. }
  21. }

  22. ?>

And here’s a little action, which renders generated WSDL for this class using Zend_Soap_AutoDiscover:

  1. ...
  2. /**
  3. * Action that renders WSDL
  4. * Controller: IndexController
  5. */
  6. public function wsdlAction() {
  7. $wsdl = new Zend_Soap_AutoDiscover();
  8. $wsdl->setClass('Writer');
  9. $wsdl->handle();
  10. exit;
  11. }
  12. ...

Now if you go to http://yourhost/index/wsdl you should see a properly generated WSDL of your web service. Please note, under default conditions, Zend_Soap_AutoDiscover will register URL of your index.php file as your SOAP service URL.

Lets expose our Writer and it’s write method – for that, create a SOAP server using the URL of WSDL. I don’t see any reasons to use Zend_Soap_Server for this example, so I’m using PHP SOAP extension’s functionality:

  1. ...
  2. /**
  3. * SOAP server action
  4. * Controller: IndexController
  5. */
  6. public function indexAction() {
  7. $server = new SoapServer('http://yourhost/index/wsdl');
  8. $server->setClass('Writer');
  9. $server->handle();
  10. exit;
  11. }
  12. ...

After the server is ready, you can test your service with SoapClient. If message is successfully logged you should get true in the response:

  1. ...
  2. $client = new SoapClient('http://yourhost/index/wsdl');
  3. $response = $client->write($message);
  4. var_dump($response); // true or false
  5. ...

That’s it. Now you should be able to easily create the WSDL for your object, set up a SOAP server and to test it with a SOAP client.

No comments:

Post a Comment