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.
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.
- timeout The timeout for the requests defaults to 30 seconds.
- persistent Should the connection be persistent, opened with pfsock.
- defaultUrl The default URL to be used.
- port The port for the connection defaults to 80.
- protocol The protocol for connection defaults to tcp.
- followRedirect Should redirects be followed. Defaults to
false
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:
- $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.
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.
- 'methodName' => 'testFunc',
- 'foo', 'bar', 1
- )
- );
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.
Search
Recent Posts
- Getting a new Oven, Migrating from CakePHP 1.1 to 1.2
- Code Completion for CakePHP in Eclipse
- CakePHP RC3 released and CakePHP 1.1 new release
- Book Review: CakePHP Application Development
- Providing Contextual Form Help with Mootools
- Creating gracefully degrading javascript and enabling progressive enhancement
- Server up and down time
- Acl Menu Component
- Github hooked up
- Auth and Acl - Automatically updating user Aros
Comments
David Boyer on 4/7/08
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 on 4/7/08
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 on 5/7/08
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 on 9/7/08
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); }Juan Basso 1 week, 1 day ago
Very nice! I’m needing this im my company. I have created a datasource, but not is the best. This is better.
When you not use a database, simple make $useTable = false in model?
Some issues: – In setup (line 104), use array_merge until am. – In line 342, use isset($heads[‘Set-Cookie’]. This is better than array_key_exists. – I’m not tested in action, but the behavior not parse XMLRPC response?
Thanks for all.
JadB 3 days, 2 hours ago
Nicely done.. Was trying it out and on sites that return bad cookie parts, the setCookie sometimes echoes a
Notice: Undefined offset: 1 in /usr/www/dev/indv/jad/monitorize/models/behaviors/webservice.php on line 229Basically because the part in question just doesn’t include any ‘=’
Adding an
eregi('=', $part)check right before it solves it.Thanks again!
Have Something to say?