01.05Tutorial - AS3 & REST web services with RESTProxy - Part 1
Hi Everyone,
[UPDATE Jan 19th, 2008]
I've just modified RESTProxy.php to handle gzip encoding from the client-side. It was quite simple. I was trying to consume web services on Discogs.com and it requires that you accept gzip encoding..
a while back, almost a year ago now, I published a little package of code called RESTProxy. This proxy is accessed from Flash AS3 code through AMFPHP to process HTTP requests otherwise not possible because of cross-domain limitations or because flash.net.URLLoader doesn't allow the operation. True in Flex you have HTTPService which allows you the full spectrum of REST web service calls, however not so in flash.
In this tutorial I'll cover when to use RESTProxy, guide you through it's installation then show you a few examples.
URLLoader vs. RESTProxy
The following chart explains the advantages of using RESTProxy over URLLoader.

However, it is possible all you want is to consume webservices using POST and GET, on a host with a valid cross-domain.xml file; in which case you do not need RESTProxy. I developed RESTProxy to consume the more advanced data services from the YouTube GData Web Services.
How it works
The idea is simple: you use a proxy on your own webserver to execute all your requests, therefore getting around the limitation of URLLoader and enabling you complete flexibility over your requests. This is how URLLoader *should* be, but alas people at Adobe think that Flash is not for hardcore coders; hence they offer the flexibility in Flex but not Flash.
The following diagram should help

Installing RESTProxy
This is probably the tricky part for you guys with less server-side experience; even though that is nothing hard about it. You do need a working hosting space with PHP 5.x and the cURL library installed, plus FTP access.
- First download AMFPHP 1.9 beta 2 here.
- Next you need to create a directory on your hosting space and unpack the files there. I like to call it
amf3since AMFPHP does implementAMF3encoding. Note that AMF stands for ActionScript Messaging Format, and the 3 is for version three. The other earlier version was AMF0. - Then, notice there is a
servicesdirectory inside of the unpacked files, right under amf3. This is where you need to upload RESTProxy.php. - You will need to remove the .txt extension at the end; I had to do this to let you see it's content, otherwise my web server would have interpreted it and executed the code instead of showing it to you.
- Finally, upload the crossdomain.xml file found here on your host and put it at it's root.
Testing RESTProxy
For those not familiar with the flash.net.NetConnection object, I will walk you through it. NetConnection enables you to establish a AMF encoded connection to a server, over which you can transfer information. It is in fact a kind of protocol that sits on top of HTTP. You can connect to Flash Media Server, AMFPHP, RED5, and a bunch of other server software that implement AMF encoding.
In our case, we are interested in three things:
- Connecting to the AMFPHP Gateway
- Calling the service method, in this case RESTProxy.request
- Receiving the response and listening for potential errors
Since NetConnection implements the IEventDispatcher interface, it enables you to easily listen to the following events which can prove important:
AsyncErrorEvent.ASYNC_ERRORIOErrorEvent.IO_ERRORSecurityErrorEvent.SECURITY_ERRORNetStatusEvent.NET_STATUS
These events, if dispatched would pertain to the connection between your flash application & AMFPHP sitting on your server, and not the actual call to the service you which to consume.
Next, we are interested in the following methods of NetConnection:
connect(url:String)call(method:String, responder:Responder, args...)
And it can prove important to choose your object encoding too as shown in the code snippet below. The potential error events are kept out for simplicity.
-
package newcommerce.restproxy
-
{
-
import flash.display.MovieClip;
-
import flash.net.NetConnection;
-
import flash.net.Responder;
-
-
public class RPTest extends MovieClip
-
{
-
protected var _conn:NetConnection;
-
protected var _responder:Responder;
-
protected var _proxyUrl:String = "http://www.martinlegris.com/amf3/gateway.php";
-
-
-
public function RPTest()
-
{
-
_conn = new NetConnection();
-
-
_conn.connect(_proxyUrl);
-
-
_responder = new Responder(onResult, onFault);
-
_conn.call("RESTProxy.request", _responder, "http://www.google.com", "GET", [], [], [], 0);
-
}
-
-
protected function onResult(result:Object):void
-
{
-
// trace out the contents of result
-
for (var i in result)
-
{
-
trace("result[" + i + "] = " + result[i]);
-
}
-
}
-
-
protected function onFault(fault:Object):void
-
{
-
// trace out the contents of fault
-
for (var i in fault)
-
{
-
trace("fault[" + i + "] = " + fault[i]);
-
}
-
}
-
}
-
}
(you can download this example here)
Running the test returns the following:
result[content] = { the actual HTML generated by http://www.google.com goes here }
result[requestId] = 0
result[effectiveUrl] = http://www.google.com
result[header] = HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Date: Tue, 06 Jan 2009 04:55:53 GMT
Expires: -1
Content-Type: text/html; charset=ISO-8859-1
Set-Cookie: PREF=ID=38745ba5ba698543:TM=1231217753:LM=1231217753:S=80giACnwrOAOFWJj; expires=Thu, 06-Jan-2011 04:55:53 GMT; path=/; domain=.google.com
Server: gws
Transfer-Encoding: chunked
result[httpCode] = 200
result[contentType] = text/html; charset=ISO-8859-1
result[sentHeaders] = GET / HTTP/1.1
User-Agent: Shockwave Flash
Host: www.google.com
Pragma: no-cache
Accept: */*
As you can see, it worked!
Parsing the results
The result object returned by RESTProxy is an object (associative array) containing the following properties (keys):
header-- the HTTP headers returned by the requestcontent-- the content returned by the requesthttpCode-- the httpCode returned by the servercontentType-- the type of content as identified by the remote servereffectiveUrl-- in case of multiple re-directs, this is the last URL called, the actual targetsentHeaders-- the headers sent by the RESTProxy to the target serverrequestId-- a simple identifier that you sent along with the request, to easily map requests with responses
Therefore, in the onResult function you could do like this
-
protected function onResult(result:Object):void
-
{
-
trace("result.requestId:"+result.requestId);
-
trace("result.httpCode:"+result.httpCode);
-
// ...
-
}
RESTProxy will ALWAYS return all 7 elements in its return object.
This is what the whole transaction looks like in ServiceCapture by Kevin Langdon.

I have used ServiceCapture for years, it rocks. You can also use Charles.
End for now..
That's it for today. In part 2 I will describe how to pass custom headers and GET & POST variables. You can have a peak at this information in a past post.
Martin
Related posts (automatically generated):
- Tutorial - Consuming REST web services in ActionScript 3 - Part 1
- Tutorial - Consuming REST web services in ActionScript 3 - Part 2
- Tutorial - Consuming REST web services in ActionScript 3 - Part 3
- Tutorial - Consuming REST web services in ActionScript 3 - Part 4

Leave a Reply