Tuesday, January 06, 2009

No, actually, I did mean POST

I'm working on a Flex UI which is driving a RESTful service backend. Well, OK, the current implementation uses standard HTTP verbs but isn't fully bought in to hypermedia-as-the-engine-of-application-state, so I guess it's RESTful-ish. Sosumi.

Naturally, when I'm creating a new resource on the server side from the client, I want to use POST. That's what POST is for, after all. Suppose I want to create a sub-resource of some given URL. It might be a new state resource, such as a record of a first-class representation of a user action. Crucially, I may want to fill in the details of the resource later, with PUT. Initially, it's enough that the resource exists at all. Here's my flex code:

protected function createOnServer( url:String, value:Object = null ):HTTPService
    var _req:HTTPService = new HTTPService();
    _req.url = url;
    _req.resultFormat = "text";
    _req.addEventListener( ResultEvent.RESULT, resourceCreationDecodeCallback );
    _req.addEventListener( FaultEvent.FAULT, resourceErrorCallback );
    _req.method = "POST";

    trace( "created post request object, about to send()" );

    return _req;

Pretty straightforward stuff. Create an HTTP service, set the method to POST, send() and wait for the callback. Invokes HTTP POST on the service endpoint, right? Wrong. Inexplicably, if the value of the call is null – the default value – Flex will silently transform the method from POST to GET. Huh? How does that work? Even if, in some way that's entirely not obvious to me, it's Bad to send an empty HTTP POST, the client should signal an error. Not silently change the semantics of the HTTP request to something completely different.

The solution, or rather, workaround, for this is to always invoke the above method with a value, even if that's not called for in the design of the resource interaction:

createOnServer( "http://localhost:8080/demo/api/some/resource", 
                Object({dummy:"dummy"}) );

del.icio.us: flex3, web-service.

No comments: