Supporting PUT & DELETE in the Zend Framework

Creating a RESTful (Representational State Transfer) Web service is not simply about serving read-only content through HTTP GET requests. It’s about using the full range of HTTP’s constrained interface to allow clients to consume or create resources within your service. Take a look at CouchDB, for example. Its initial releases look very promising, and the server accepts GET, POST, PUT, and DELETE requests to manipulate resources in the system. I can’t wait until the project implements authentication and authorization features; then, it will look much more attractive for real-world use.

But I digress…

I’ve never been too happy with the Zend Framework’s RPC-based approach to creating RESTful Web services with Zend_Rest_Server, even though I have seen some good discussion about using routes and Zend_Rest_Server to create a resource-oriented architecture. Rather than get too in-depth about this issue, I’ll just point to this thread and save my full thoughts on Zend_Rest_Server for another day.

Suffice it to say, Zend_Rest_Server is not focused on resources but, instead, what you can do with those resources (procedures, methods, verbs) and also assumes you’re only ever going to provide an XML-based, read-only REST service. With REST, this is not the case, and, with the publication of the Atom Publishing Protocol (a protocol that follows the REST architectural style) as RFC 5023, now is the time more than ever to grasp the read-write capabilities of the RESTful Web.

But I digress (again)…

I’ve recently been wrapped up in an effort to design and implement a RESTful API using the Atom Protocol for a project at work. We are using the Zend Framework as the underlying framework for the project, so, in order to follow the Atom Protocol, I needed to support the HTTP methods PUT and DELETE. Apache can handle GET and POST easily because the request itself tells Apache the resource to use when processing the request. With PUT or DELETE, the resource identified by the request may not even exist, so Apache needs you to specify a script to process the request. To do this, I added the following lines to my virtual host configuration:

# PUT and DELETE support
Script PUT /index.php
Script DELETE /index.php

Now, all PUT and DELETE requests are handled by the Zend Framework bootstrap script and the dispatcher handles them in the same way it handles GET and POST requests.

To further support other HTTP methods and the REST architectural style, I’ve proposed the addition of the following methods on the Zend_Controller_Request_Http class:

  • isGet() - Was the request made by GET?
  • isPut() - Was the request made by PUT?
  • isDelete() - Was the request made by DELETE?
  • isHead() - Was the request made by HEAD?
  • isOptions() - Was the request made by OPTIONS?
  • getEntityBody() - Return the raw entity body of the request, if present

It’s a very simple addition, but feel free to comment on my patch and offer any improvements or additions.

See also PUT method support in the PHP manual.