Information

  • You need first login to contribute comments.

Connecting Flex 4 and RESTful Web Services using Zend Framework


Connecting Flex 4 and RESTful Web Services using Zend Framework

David Flatley

Introduction

With Adobe's latest incarnation of the Flex Framework and the Flash Builder integrated development environment (IDE), creating truly engaging front-end clients is now more streamlined. Some of the useful tools and features covered in this article are the Data/Services, Test Operation, and Network Monitor additions to Flash Builder. In this article, I explain how to set up a simple Representational State Transfer (REST) service using the Zend Framework 1.9 locally and connect to it in the Flex 4 application.

Prerequisites

To get the most from this article, you should have a basic knowledge of the Zend Framework version 1.9. Development experience locally on your machine with Apache Server distributions like XAMPP, WAMP, or MAMP is helpful but not mandatory. You will need to deploy the server-side application on Apache running PHP. There is no database connectivity for this article.

Finally, you must have Flash Builder with PHP development tools installed or some flavor of the Eclipse IDE with the Flash Builder plug-in to complete the examples in this article.

Setting Up the Development Environment

Like anything else, setting up your environment for PHP and Flex development is a matter of personal preference. To get started with this article, I suggest using either a PHP version of the Eclipse IDE or Flash Builder 4 with PHP Development Tools (PDT) on top of it.

In this article, I use MAMP on Mac OS X and XAMPP on Windows to deploy the Zend REST service application. These two Apache distributions come complete with MySQL and PHP and are immensely helpful for local development when you want to set up your environment quickly.

The Zend command-line tool (CLI) will come in handy for rapidly setting up the PHP server-side project. See the section "Where to Go from Here" if you need help installing any of these tools or IDEs.

Creating the Zend Application

To create the Zend server-side application, I use the Zend CLI. To verify that the Zend CLI is hooked up properly on your system, open a command prompt and type:

zf show version

Note: Depending how you set up the tool, your actual command may be differently named. Ultimately, the zf is pointing to the zf.bat file on Windows or the zf.sh file on a UNIX-based system that comes with the Zend Framework.

At the command prompt, change directly to the local server's Web root. In XAMPP and MAMP, that's the htdocs folder. To create the project, type (see Figure 1):

zf create project fx4_zend_rest

Figure 1. Using the Zend CLI to create the PHP project

Change directory again to the newly created fx4_zend_rest folder the CLI just created. Next, issue one more command to create the RestController. Figure 2 shows the DOS command prompt on Windows. (I'll be going back and forth between Mac OS X and Windows periodically to show the versatility of the tools and IDEs for PHP and Flex development.)

zf create controller rest

Figure 2. Creating the project and RestController in Windows

The rest of the application is easier to code by hand. The first thing to do is ensure that the application is running. On your local host, browse to the project's public folder. In my setup, the URL is http://localhost:8888/fx4_zend_rest/public/ on Mac OS X and http://localhost/fx4_zend_rest/public on Windows.

You should see the standard Welcome to the Zend Framework page at this point.

Setting Up the Project in Eclipse

Whether you're using Eclipse with the Flash Builder plug-in or Flash Builder with the PDT plug-in, these steps are more or less standard in all flavors of the Eclipse IDE:

  1. Start your IDE, and then click the PHP perspective.
  2. Click File > New > PHP Project.
  3. Name the project fx4_zend_rest, and create the project from the existing source.
  4. Browse to the Zend application you just created in your server's Web root, then click Finish.

In the PHP Explorer, you should see the full Zend application ready and waiting for its RESTful service. Let's move to that now.

Building a RESTful Web Service

To build the actual REST services, begin by creating a new folder under the application folder called services. There, create a new PHP class called Gizmos by clicking File > New > PHP File. This is the class to which the RestController will defer all its actions. Once the services/Gizmos.php file is created, it's back to the RestController to fill in those actions.

Inside the RestController, add the following actions:

public function getAction()
{
}
    
public function postAction()
{
}
 
public function putAction()
{
}
 
public function deleteAction()
{
}

The standard actions for a RESTful Web service are GET, POST, PUT, and DELETE. These actions route the calls from Flex 4 to the Gizmos class, where the real work of the services will be handled.

Before moving on to each action in the controller, set the view not to render via an init() function. Because the REST service is just returning XML, the application doesn't need to worry about the view.

 
public function init()
{
    $this->_helper->viewRenderer->setNoRender(true);
}

Inside the other actions of the RestController, the next step is to defer handling of the services to the Gizmos class you created earlier. Add the following code to the main action methods inside the controller:

 
 
class RestController extends Zend_Controller_Action
{
	public function init()
    {
        $this->_helper->viewRenderer->setNoRender(true);
    }
 
	public function indexAction()
    {
		$this->getResponse()
            ->appendBody("From indexAction()");
    }
    
 
    public function getAction()
    {
    	
    	$server = new Zend_Rest_Server();
		$server->setClass('Gizmos');
		$server->handle();
		exit;
            
    }
    
    public function postAction()
    {
        $server = new Zend_Rest_Server();
		$server->setClass('Gizmos');
		$server->handle();
		exit;
 
    }
    
    public function putAction()
    {
        $server = new Zend_Rest_Server();
		$server->setClass('Gizmos');
		$server->handle();
		exit;
 
    }
    
    public function deleteAction()
    {
        $server = new Zend_Rest_Server();
		$server->setClass('Gizmos');
		$server->handle();
		exit;
 
    }
 
}
 

This code tells the controller that when an action is requested (GET, POST, PUT, DELETE), it must create a new instance of the Zend_Rest_Server class and set the Gizmos class to handle each one. I do this to keep things simple for this article: You could just as easily handle each action in the controller with separate classes.

The RestController is done at this point. The real work of the REST service will be handled by the Gizmos class. To ensure that the Zend application is aware of the Gizmos class, add the following lines to public/index.php:

 
 
class Gizmos
{
	public function getGizmos()
	{
	}
	public function postGizmo($query)
	{
	}
	public function putGizmo($query)
	{
	}
	public function deleteGizmo($query)
	{
	}
}

These methods represent the actions set earlier on the RestController. This is where the Zend application handles the actual work for each method of the REST service. To keep things simple, this class doesn't connect to a database; rather, its methods create and manipulate XML documents to return to the client. The GET action of this REST service will be represented by the getGizmos() method, POST to postGizmos(), and so on.

The getGizmos() method serves up a list of Gizmo objects represented by XML. Because the focus of this article is mainly on the Flex 4 client, this XML serves as a good example of how to keep things as simple as possible. In a real-world application, a developer would likely need to connect to a database that stores (in this case) gizmos. Why gizmos? Because everyone knows that gizmos are so much cooler than gadgets, widgets, and doo-hickies.

The following code shows the getGizmos() method with its new functionality. It simply creates an XML document, loops five times, and populates the fictitious value objects (gizmos) with random numbers of hoses, sprockets, and screws. Then, it returns the XML.

 
public function getGizmos()
{
		
	$xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
  	$xml = $xml . "<response><gizmos>\n";	
	
	for ($i = 1; $i < 6; $i++) 
	{
		$xml = $xml . "<gizmo id=\"" . $i . "\">\n";
		$xml = $xml . "  <hoses>" .  rand(1, 30) . "</hoses>\n";
		$xml = $xml . "  <sprockets>" .  rand(1, 30) . "</sprockets>\n";
		$xml = $xml . "  <screws>" .  rand(1, 30) . "</screws>\n";
		$xml = $xml . "</gizmo>\n";
	}
		
		$xml = $xml . "</gizmos></response>";
		
		$response = new SimpleXMLElement($xml);
		$response->addChild('status', '200');
		$response->addChild('success','true');
		
		return $response;
	}
 

This code serves as the application's GET method for the REST application programming interface (API). To make sure this code is working, browse to the application on your localhost. On Mac OS X, my URL is http://localhost:8888/Flex4_Zend_REST/public/rest/get?method=getGizmos. On Windows, under XAMPP, my URL is http://localhost/Flex4_Zend_REST/public/rest/get?method=getGizmos Figure 3 shows the returned XML.

Figure 3. REST service returning XML from the getGizmos (GET) call

The rest of the methods in the Gizmos class return simple XML as part of the REST service's API to load on the client side. You can use the source code provided with this article for the rest of the class.

Setting Up the Flex 4 Project

If you're using Eclipse with the Flash Builder plug-in, you can simply right-click the fx4_zend_rest project folder and click Add/Change Project Type > Add Flex Project Type. Doing so adds a new Flex project to your existing Zend application.

When the window opens, leave the defaults, and click Next. On the next page, the Web root folder should point to your htdocs folder. The root URL is the root of your localhost. See Figure 4 and Figure 5 for the rest of the settings.

Figure 4. Adding a Flex project type to the existing project in Eclipse

The Application server type is set to PHP for you. Be sure to enter your correct localhost settings and validate the configuration before proceeding.

Figure 5. Enter the Application server location settings according to your local environment.

Click Finish. You'll be asked if you want to switch to the Flash perspective. Of course you do! This is where the fun begins.

The Flex 4 Application

After setup, the Flash Builder project is ready for some data. To illustrate a point, I'll first show you how to connect to the REST service using hand coding. In the fx4_zend_rest.mxml file that was created, you'll notice the <Declarations> tag pair.

This is the place to put your non-visual MXML components in Flex 4 style. In previous versions, you could place things like an <mx:HTTPService /> component anywhere in your code, but going forward, you'll need to place them inside the <Declarations> tag.

Typically, to contact the Zend REST service created earlier, you would use the HTTPService component. Inside the <Declaration> tags, add the following code:

 
<fx:Declarations>
	<s:HTTPService id="service" url="http://localhost:8888/fx4_zend_rest/public/rest/get?method=getGizmos"result="handleResult(event)" fault="handleFault(event)" resultFormat="e4x" />
</fx:Declarations>

Open a script block at the top of the document, and write the handleResult() and handleFault() methods.

 
<fx:Script>
		<![CDATA[
			import mx.controls.Alert;
			import mx.events.FlexEvent;
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.ResultEvent;
			
			protected function init():void
			{
				service.send();
			}
			
			protected function handleResult(event:ResultEvent):void
			{
				trace(event.result.success);
				if(event.result.success == "true"){
					var xml:XML = new XML(event.result);
				}
			}
			
			protected function handleFault(event:FaultEvent):void
			{
				trace(event.message);
			}
			
			
		]]>
	</fx:Script>

To kick off the call to the server, add the following code to the <Application> tag's creationComplete event:

creationComplete="init()"

In its simplest form, Flex is ready to call the REST service at this point. With this code, you instantiated an HTTPService component, gave the complete URL to the getGizmos method, and set result and fault methods to handle a success or failure for the call.

If you debug the application now, you should see "true" from the event.result.success traced out in the Flash Builder console panel.

Useful Tools in Flash Builder

Adobe Flash Builder contains many useful tools, such as Network Monitor and Data/Services.

Network Monitor

That example was the simplest and most typical way to connect Flex to the REST service, but with the latest version of Flash Builder (plug-in or stand-alone), you'll be armed with an arsenal of data-connectivity features and tools to make your development life easier, faster, and more streamlined.

For starters, click Window > Show View > Other, then browse to the Flash Builder folder for the Network Monitor and click OK. Run the application again, and take a look at the Network Monitor panel. You'll see the call to the server with the resulting XML and status as well as a bunch of gizmos.

Many other third-party tools are available to help you see what's going on behind the scenes of a Flash or Flex client application making calls to a server, but having the Network Monitor built right into Flash Builder is a major help. In conjunction with the debugger, this feature will save a lot of time when troubleshooting issues between the client and server.

Data/Services

The new data-connectivity features in Flash Builder are immense. I go over some of the ways you can take advantage of these new features to speed up your development time, but I highly recommend that you spend some time researching and experimenting further to see what's possible.

In the init() function, comment out the service.send(); for now. To connect to the REST service with the new Data/Services features, click Data > Connect to XML. Because the REST service returns XML, it makes sense in this case to go this route. Generally speaking, though, you could choose Connect to HTTP or Connect to PHP for similar functionality.

If you deployed a simple PHP file instead of a service wrapped with the Zend Framework, you might choose Connect to PHP to make things easier. By choosing Connect to XML in this example, you're taking the most direct path to consume the REST service. To illustrate this explanation further, take a look at the window that opens after you've made your selection.

Figure 6 shows the settings for the Connect to XML Service window. Choose the URL option, and enter the full URL for the getGizmos method of the REST service in the URL field. Type GetGizmos for the service name, and then click Invoke.

Figure 6. Connect to XML Service window in Flash Builder

When the result returns inside this same window, click the Select node drop-down menu, and then click gizmo. This is the actual resulting XML returned from invoking the call. Flash Builder presents the nodes for you to configure a return type for the value object.

When you click Finish, Flash Builder creates a few new classes behind the scenes. Take a look at the services.getgizmos package that was automatically created. Inside it, you'll see two classes: _Super_GetGizmos and GetGizmos. These are the actual service wrapper class and a subclass that allow for further customization should you need it. You can see Flash Builder automatically used the URL and method provided from the Connect to XML Service.

Inside the valueObjects package, take a look at the _Super_Gizmo class. This class is an auto-generated value object that was created when you selected gizmo from the Response drop-down menu in the Connect to XML window. Both the GetGizmos and Gizmo classes are where you'd add any new functionality or override any features you want to change. With a name like Super Gizmo, though, I don't know if improvement is possible. It sounds like a great sequel to a popular 80s movie.

Test Operation

The auto-generated code from the prior steps needs no further editing for this sample. So look at the Test Operation features. Click the Data/Services panel, if it's open. Otherwise, click Window > Show View > Data/Services (see Figure 7).

Figure 7. Data/Services panel with the GetGizmos service auto-generated by Flash Builder

Right-click the getData() method in this panel, then click Test Operation. Its panel opens already showing the getData method ready to go. Click Test; you'll see the resulting response from the server once again. If this particular method on the server required parameters, you could send them along to test different responses in this same panel. In this specific case, the getGizmos method on the server requires none.

Now that you know Flash Builder is talking to the REST service, it's time to get something happening visually. In Flash Builder, it's a minor effort to populate a DataGrid or List with the resulting value objects from this server call. If you enter Design Mode, you can drag a DataGrid from the Components panel directly onto the application. After that, simply drag the getData() method from the Data/Services panel onto the DataGrid component that you just dropped. The Bind To Data window will open as a result (see Figure 8), and it will already be populated with the correct information; all you need to do is click OK.

Figure 8. The Bind To Data window opens as a result of dragging a method from the Data/Services panel onto the DataGrid component.

There's only one more step to go in this process. Click Source next to Design Mode to return to the code. You'll see that Flash Builder did a few things in the background to connect the DataGrid with the getGizmos method of the REST service. It added the GetGizmos service and a CallResponder inside the <Declaration> tags, and it bound the DataGrid's dataProvider property to the CallResponder's lastResult.

It also created a dataGrid_creationCompleteHandler method to automatically fire the server call. However, you need to tell the GetGizmos HTTPService which method on the server you want to hit. In this case, it's getGizmos. Change the single line of code to:

getDataResult.token = getGizmos.getData("getGizmos");

You can run the application at this point, and you should see the DataGrid populated with results from the REST service's getGizmos call (see Figure 9).

Figure 9. The DataGrid populated with results from the Zend REST service data

Now that you see the whole process of getting the data into Flex, I'll leave the rest up to you. Try to post a new gizmo to the REST service. Hook it up with the Connect to XML Service feature, invoke the service by sending a parameter along with the call, and check out the response that comes back. In your Web browser, the URL would be something like http://localhost:8888/fx4_zend_rest/public/rest/post?method=postGizmo&query=4.

To keep this article relatively short, I'm not going to go into detail about the other data-connectivity features of Flash Builder. You can see for yourself that many preexisting features are available to get your front-end client up and running quickly, just as you did in this article. For example, you can right-click the getData() method in the Data/Services panel and generate a fully functioning form based on the service created earlier. Then, you can manipulate and send the data back to the server. Using these same tools, you can connect to a variety of server-side functionality and applications built with Java, PHP, Microsoft .NET, Adobe BlazeDS and LiveCycle, and more.

You can also create basic starting points for Zend applications directly from Flash Builder. For example, you can have Flash Builder generate typical create, read, update, delete (CRUD) functionality based on a database table and greatly shorten your development time by bypassing some of the more tedious and typical tasks you'd normally code by hand.

Conclusion

These features save countless hours of development time and help to shed light on the previously more obscure zone between the client and server. I've had many projects where the server-side team would change an API without telling me, and I would have to spend some time hunting down the changes. But with the Network Monitor and Data/Services features, you can greatly reduce the pain and spend more time concentrating on a great interface for the client side.

For More Information

I encourage you to continue with what you've started in this article by connecting Flex 4 to the remaining REST service methods and successfully loading and manipulating the data to and from the server. Listed below are some useful links to some of the tools and software used in this article:

Comments (Login to leave comments)

Wednesday, March 3, 2010
NOT RESTFUL
7:18PM GMT · groovepapa
Thursday, March 4, 2010
WHAT WOULD YOU CHANGE?
9:22PM GMT · dflatley
:S/REST/RPC/
9:42PM GMT · groovepapa
CAN'T HELP THE CRAPINESS OF THE ZEND_REST_SERVER
10:27PM GMT · dflatley