In this article, I will show you that forms sent by browsers to a server can only use GET
and POST
HTTP methods and which workaround to apply in order to still use a REST backend.
REST web-services are becoming more and more common in today’s landscape. We can only imagine the reasons, but I guess that SOAP’s structured approach is only useful in the most complex use-cases and is overkill the rest of the time. On the contrary, REST is quite easy to setup.
In the Java world, REST has its own specification, JAX-RS with JSR 311, and is supported by all major frameworks :
- Sun Jersey, the reference implementation
- Apache CXF
- RESTlet
- etc.
In my humble opinion, it is not inconceivable that, given the adoption of REST, the next step would be the development of REST backends accessible by standard clients and browsers alike, in order to factorize code and thus decrease costs.
Traditionallly, making a resource accessible on the web is realized through a hyperlink. Hyperlinks use the GET method. Likewise, REST is based on using the HTTP methods where each has an associated verb:
HTTP method | Verb |
---|---|
POST |
Create |
GET |
Read |
PUT |
Update |
DELETE |
Delete |
Unluckily, the real world comes into play. In order for this to work, the HTML 4 specification is a big obstacle in the way:
The FORM element […]
Method: this attribute specifies which HTTP method will be used to submit the form data set. Possible (case-insensitive) values are "get" (the default) and "post".
The implication is that HTML 4 compliant browsers will only let you read and create but not update nor delete. For example, the versions of Firefox and Internet Explorer I used, respectively 3.5.6 and 6.0 (!) use POST for POST and GET for everything else. That’s a real case against using REST. There are some workarounds, though.
The first one is not to use the HTTP method for the verb but to put it in the URL. Thus
- to access a customer, one would use http://frankel.ch/get/customer/1
- and to remove one, http://frankel.ch/delete/customer/1
This clearly violates REST’s principle of using the HTTP method for the verb but this works for simple cases.
The second workaround is a bit more complex but it has two big advantages: it conforms to REST principles and it is usable with most modern-days browsers.
The trick is to use a neat little object created by Microsoft but now implemented everywhere, the XMLHttpRequest
object.
Yes, this is the object at the foundation of Ajax but is is also the solution of our problem.
XMLHttpRequest
open()
method takes two parameters, the first being the HTTP method to use for accessing the url (which is the second parameter).
Now you can pass the verb you want, like the following example.
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('DELETE', 'http://frankel.ch/customer/1');
xmlhttp.send(null);
Morevover, you can not only use the 4 CRUD verbs but also any verb you want.
This solution has two main limitations:
- it requires modern-day browsers since the
XMLHttpRequest
object is not available in more ancient ones - it requires JavaScript, so you need to enable it on client browsers and you need to manage browser compatibilities. For example, the above script with Firefox 3.5 but not IE 6 (and to be blunt, I’m not really bothered by it)
It seems this hack will be rendered useless by the HTML 5 specifications which declares (in their draft state) that all 4 basic CRUD verbs will have to be supported.
You can find an example for this article here. Tu use, navigate to http://localhost:8080/httpmethods/ if deployed in Eclipse. It was tested on Firefox 3.5 and works on it flawlessly. On the contrary, it doesn’t work for IE 8 since my script is not crafted to be cross-browsers. For Tomcat users, you have to add JSTL capabilities to Tomcat (meaning adding standard.jar and jstl.jar in the commons/lib directory).