Introducing the Webservice Behavior

Jul 04 2008

As webservices grow so does the need for being able to communicate with them in an easy fashion. This simple blog alone uses 2 webservices. The recent tracks at the bottom is a feed I pull from Last.fm and my spam protection is provided by Akismet. When first building my site I looked for an already built solution and found a partial solution in Felix Geisendörfer’s WebModel. However, I wanted to remove its dependancy on cURL as it is not always available, and transform it into a behavior. Transformation to a behavior was an easy process. Removing curl and manually writing all the Socket code was not an appealing prospect. Thankfully, CakePHP 1.2 has the new CakeSocket class which eases the creation of socket connections. The result is a behavior that has no extension dependancies and is a behavior for easy reuse. This is a PHP5 class, so if you are on PHP4 too bad.

Using the Webservice Behavior

Using the webservice behavior is quite easy. Simply add it to the $actsAs array for your model.

Show Plain Text
  1. $actsAs = array('webservice');
  2.  

Is the most simple use of it. There are a number of setup options that you can set as well. They are mostly related to the socket connection, and in most cases don’t need much fiddling.

Above are the configuration options that can be set in the model $actsAs array. They can also be set on any request through $options[‘options’]

Making Requests

Requests are made with the request() method. A simple use would look like:

Show Plain Text
  1. $this->Model->request('get');

This would make a request against the defaultUrl set in the model settings and return the content of that request. The request() method connects to the defaultUrl if no url is supplied. Several request types are supported with ‘get’, ‘post’ and ‘xml’ being the completed types. I have plans to add SOAP as well, as soon as I can wrap my head around the documentation. A second argument allows you set additional headers, data, url, and options for the connection.

Show Plain Text
  1. $this->Model->request('get', array('data' => array('q' => 'mark story'), 'url' => 'www.google.ca/search')));

The above would do a search on google for ‘mark story’.

Debugging your Requests

There is built-in capabilities to introspect on what is going on in your request calls. Using getRequestInfo() will return an array of information pertaining to the last made request. Headers for both the request and response, as well as cookies, data and connection options will be returned. I found this to be very handy in my own development, and I hope you will as well.

Bonus Round XMLRPC

As a bonus when downloading the WebserviceBehavior you get an XmlRpcMessage class as well. This is a very simple class to enable the transmission of XMLRPC requests. I haven’t done any testing with complicated payloads. But for simple requests it works quite well. When making requests with the type of xml, supplied data is automatically converted into an XMLRPC message and sent for you. The one caveat is that you need to supply a methodName as well.

Show Plain Text
  1. $data = array(
  2.     'methodName' => 'testFunc',
  3.     'data' => array(
  4.         'foo', 'bar', 1
  5.     )
  6. );
  7. $result = $this->Model->request('xml', array('data' => $data));

This will format up an XML message and send it. You can also you the XMLRPC class on its own of course. It is a full class with a usable interface. But that is another day and another article. Included with the class are some tests, they cover the typical use cases that I have come across so far, but will be expanded as I use it more, so check back for updates to the classes and tests.

As always I’d love to hear any feedback you have for this, and I hope you find them useful.

Update I’ve added in Kim’s suggestion to allow multi-dimensional array to be posted. Thanks Kim.

Download WebserviceBehavior


Comments

David Boyer Fri, Jul 4th 2008, 07:31

This behaviour looks fantastic and it’s just what I’m after. I’m in the middle of building a CakePHP replacement for my wordpress blog and would love any tips on getting this to work with akismet :)

Also wanted to thank you for your Geshi helper, this is turning out to be an awesome CakePHP related blog.

mark story Fri, Jul 4th 2008, 12:34

Glad you found it useful David, I’ve got plans to release my Akismet model here as well. But if you can’t wait the API documentation gives a good overview on how to do. The API call you want is ‘comment-check’

Martin Bavio Sat, Jul 5th 2008, 09:00

Mark, really nice code! Thanks for sharing it, I´m gonna use it in my next app, that´s for sure! One detail, in your last example, I guess your variable name is called $vars, or the inverse in the request call…

Kim Biesbjerg Wed, Jul 9th 2008, 19:07

Hi Mark,

Great behavior! I have made a little enhancement to the _formatUrlData function to allow requests with multidimensional arrays and strings. Hope it’s readable :

	protected function _formatUrlData($params) {
		if (is_array($params)) {
			$this->_data = http_build_query($params, '', '&');
		} else {
			$this->_data = urlencode($params);
		}
		$this->__setInfo('data', $this->_data);
	}

Have Something to say?

*
* (Never published, I promise)
* You can use Textile markup, but be reasonable

Recent Artwork

  • Shuriken 2
  • Clumsy Penguins
  • Balloon Animals
  • Metal in the air! (vertical)
  • Cleavers
  • Waiting