Wrapping an Existing Class
The main functionality of the service was written in a class that had no awareness that it was a service – this is a similar approach to the one I described when I wrote about the PHP Soap Server – start with a normal functioning class and write some unit tests for it. The example I’m using today looks like this (my real version actually connects to the database and stuff but this is a nice mock of passing in a number and getting back an array):
class Library {
public function getUserDetails($user_id) {
$details = array(
"user_id" => $user_id,
"name" => 'Joe Bloggs',
"email" => '[email protected]');
return $details;
}
}
In the soap article, you can see that wrapping a class takes just a few lines – for REST more code is required, but the idea is completely the same. In actual fact we started out with this as a soap service but then it was switched to rest – I only had to re-write the wrapper stuff and not any of the core functionality. Using the wrapper approach would also allow services to be published in multiple ways with the same underlying codebase.
Incoming Requests – Intialising the Wrapper
First of all I wrote a .htaccess file to direct all requests to the one controller file – so that all the different URLs would be handled in the same way.
As the requests came into here, I grabbed the data I needed and initialised the service class, something like this:
$service = new Rest_Service();
// instantiate the main functional class and pass to service
$library = new Library();
$service->setLibrary($library);
// create a response object and pass to service
$response = new Response();
$service->setResponse($response);
// set up some useful variables
$service->url = $_SERVER['REQUEST_URI'];
$service->method = $_SERVER['REQUEST_METHOD'];
$service->getArgs = $_GET;
$service->postArgs = $_POST;
parse_str(file_get_contents('php://input'), $service->putArgs);
parse_str(file_get_contents('php://input'), $service->deleteArgs);
$service->handle();
The variables are all read here and passed in to help decouple the systems – doing it this way allows us to initialise the Service with different incoming variables and/or a different library which can be really useful when testing, as it allows isolation of individual components. The syntax for getting the put and delete data is an interesting one, I wrote about this already in my post on accessing incoming PUT data from PHP, there are some helpful comments on that post as well.
To be continued … later parts will cover the service itself and the response format used.