Weblogs: Book Reviews

Restful PHP Web Services

Monday, February 23, 2009

Title: Restful PHP Web Services
Author: Samisa Abeysinghe
Publisher: Packt Publishing
Publish Date: October 2008

Disclaimer: I received a review copy of this book from Packt Publishing in December 2008.

Restful PHP Web Services: Restful Web services is an often-heard buzzword on the Web, and it is fairly disappointing that the real essence of what makes a Rest web service is frequently misunderstood. Unfortunately Restful PHP Web Services doesn't get it right and is littered with errors that negatively impact the content itself.

Rest is not RPC

A book that asserts Flickr as an example of a Rest web service is going to start off on the wrong foot. Unfortunately the book spends several pages detailing how to operate with that particular service as a working example of a Rest-based service.

The API is basically one single endpoint (http://api.flickr.com/services/rest/), with a collection of parameters (including one called method) that dictate what operation is being performed on what resource. This is the typical Remote Procedure Call; the URL space is broken down by function, not resources.

The fundamental principle of Rest is that the HTTP methods define the operation to perform on a representation of a resource at a particular URL. Flickr gets it wrong because URLs don't map to representations of resources, nor uses HTTP verbs as the mechanism for performing operations. It is just Remote Procedure Call.

Why use Flickr, why not use a real Rest web service, like Wordpress' implementation of the Atom Publication Protocol? At best Flickr is an API over HTTP, at worst it is a Remote Procedure Call.

Rest is about hyperlinks

Rest is about mapping representations of resources onto URLs. The Flickr API fails to do this, and to actually retrieve an image from their API you have to manually construct a URL to that image; it isn't returned to you by the API. Witness the following logic:


$image_url = 'http://farm' . $attributes['farm'] . 
	'.static.flickr.com/' . $attributes['server'] . '/' .
	$attributes['id'] . '_' . 
	$attributes['secret'] . '.jpg';

If a client has to construct a URL in this way to obtain a representation of a resource, that API isn't Restful.

Post or Put

The book improves slightly by covering the principles of Rest, but not much. It specifies POST as a means for updating a representation, and PUT as the way to create resources. The real distinction is more complicated. PUT can do both create and update, POST is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI, which means it is suitable for adding new resources. Particularly Atom uses POST on a collection to create a new member, and PUT to update an existing member.

Content types

There is no mention of content types when dealing with Rest resources. This means that a Rest client has to know what kind of representation he is getting back, because the content-type information is useless for helping determine that. Just imagine how the web would work without content types - it would be a mess.

With Atom we had specific content types for an Atom Entry and Feed, and a different content type for the Atom Service Document that described the collections available.

Curl

A useful section of the book covers using CURL to talk to servers. It is fairly useful as a starting point, but either the material is out of date or just plain wrong. Doing a GET with the code supplied did work but emitted a warning on PHP5 that there wasn't a CURL option called CURLOPT_GET. Sure enough, checking the documentation and there is no mention of this option. The code only worked because GET is the default HTTP method.

Even worse is the sample code for doing a PUT, this involves writing out the data to the filesystem and then sending the filename as a parameter using CURLOPT_INFILE. Digging around I found the more natural solution of using CURLOPT_POSTFIELDS, so it is not clear why the author had offered the convoluted file creation method and not even noting the better methods.

However useful it is to have simple working code examples of both server and client aspects of Rest, it doesn't help to ignore Rest principles in doing so. In the code sample for a PUT the author has a PHP script that is used for the URL of the resource and then claims that a PHP script is a representation of the resource. Which it isn't. A representation of a resource is data, not a piece of code that executes on that data.

Building a Rest service

The example of a library is a decent worked example of implementing Rest clients and Rest servers. However, the design and implementation skimp on architectural correctness and the code itself is just below par.

The architecture is relatively straightforward, there's a collection for users, a collection of books, and a collection of books being leant out to users.

Teaching by bad example

I tried hard to find something to like about this book. The Curl I found useful as a starting point, but I quickly realised that the author's knowledge, or working code was too sub-standard to be followed and eventually I had to sit with the PHP documentation to really figure out how to use Curl properly.

As a book about Rest web services in PHP this book falls short of any acceptable mark. I don't think it is acceptable to teach the wrong thing first until a certain level of understanding has been reached before then teaching them the right thing. This undoes any confidence or learning knowing that things need to be unlearned before continuing. Unfortunately this process isn't made clear, and many people will learn things about Rest that are not correct.

It does bother me when Rest is misrepresented in this way, because Rest is such an elegant architecture when it is allowed to be itself.

As an alternative to this book, I'd rather recommend RESTful Web Services by Leonard Richardson and Sam Ruby, and of course, anything written by Roy Fielding.


[ Weblog | Categories and feeds | 2011 | 2010 | 2009 | 2008 | 2007 | 2006 | 2005 | 2004 | 2003 | 2002 ]