26 March 2010

Google App Engine and Flex

OK so I've previously done a few projects where Flex talks to web-services which is both cool and fun. I started to think i wonder if i can get Google App Engine (GAE) to host my webservice and then Flex to do my front end. Well I'm a big fan of Open BlueDragon (OBD) and their fantastic work with GAE, so i thought I'd give it a spin.

First up the Adobe coldFusion method doesn't yet work, .cfc?wsdl was a no go, not surprising i dread to think what complexity is involved in that. There's something of a discussion of that problem here:

http://groups.google.com/group/openbd/browse_thread/thread/eec7f5664d76f47f?hl=en

However i discovered you can create and host a standard cfc and then call methods in that cfc from a standard cf template.

As the Google groups article suggested, it should be possible to just use OBD to output JSON or wxml or something to output data on a standard webpage minus the HTML. So i thought I'd give that a go.

So on my new GAE app I created a cfc with one function taking one input param and a basic case statement which returned a hardcoded string. Not rocket science. Then i created a simple cfm page to invoke that function and create a json string based on the return.

Something like this:

<cfset jayrox = structNew() />
<cfset jayrox.compName = variables.compName />
<cfset jayrox.compDesc = variables.hello1 />
<cfoutput>#SerializeJSON(jayrox)#</cfoutput>


I committed the above to GAE and then started working on the Flex app. The crux here is two fold.

First the HTTPService


<mx:HTTPService id="personRequest" url="
http://mygaelocation.appspot.com/jsonget.cfm"
requestTimeout="15" useProxy="false"
method="POST" resultFormat="object"
result="personJSON(event)"
fault="server_fault(event);"></mx:HTTPService>


Point that url to your gae cfm page and create a bindable string and a personJSON event handler:


[Bindable]
private var myJSON: String;



private function personJSON(event:ResultEvent):void
{
myJSON = String(event.result);
}


You're almost done, on application initialize run personRequest.send(); and bind a label or textarea to myJSON and you're set.

Second The crossdomain.xml

This is really really important. This took me ages to figure out, Flex and Flash when they're doing remote URL calls are trying to be security conscious. So they don't allow them unless the host (the GAE webroot) has a crossdomain.xml file. So in your war directory in GAE you need to create a crossdomain.xml file and put something like this in there:


<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>


More on this issue here:

http://www.wombatnation.com/2008/04/security-error-accessing-url

And you're done. You can drag and drop your completed .swf into the GAE war directory and there you go, Google App Engine is now hosting a complete end to end data driven Flex app.

When i get time i'll post something about making this a bit more dynamic using GAE data services.