When I decided to learn and get some first-hand experience about Rich Internet Applications (RIA) and distributed application hosting (cloud computing), I chose to do it using Flex and the Google App Engine. Flex is a mature tool that has a plethora of rich interface capabilities and is very good to connect to services on the Web. And the App Engine is a very intriguing proposition where you use Google’s infrastructure to run your application.

To share my experience and get some feedback I started a project called “Flex and Python Test”. Now this project is finished and released. The application is a very simple project portfolio that can keep a list of projects and participants. The data is kept on the client for fast response, and the modifications are sent to the server for persistence. This is what the application looks like:

The source code for this application is available on github. If you want to understand it, download it and browse the code. To help, I will explain a bit about the design.

This is the general architecture:

The client is a Flex application running in a browser. Flex allows us to have a rich interface without dealing with incompatibilities between browser implementations. The server is a Python application running in Google App Engine. The client send requests through HTTP using the AMF encoding format. This is a binary format that is very efficient for Flex applications. The server processes the requests and sends responses also encoded in AMF. The server exposes its interface in the Remote Procedure Call (RPC) pattern.

If you download the source, take a look at README.txt. It explains how to run and deploy the application. There are three directories: flex-client contains the Flex application that will run in the browser. python-client contains an alternate client in Python that you can run in your computer to initialize data, test the service and learn the API. server contains the Python service that is deployed to Google App Engine.

To build the Flex client I decided to use a Model-View-Controller (MVC) framework. A sound structure helps when you want to build larger applications. After experimenting with Cairngorm, I went for PureMVC. If I would make another iteration I might now try Mate.

With PureMVC, this is the overall architecture of my client application:

The Model represents the data. It uses the Proxy pattern to control access to the remote service. The View contains the user interface. It uses the Mediator pattern to implement Supervising Presenters that manage the interface components. The Controller contains business logic. It uses the Command pattern to execute actions that interact with several other components. The model, view and controller objects communicate using a Publish/subscribe-style Observer notification scheme.

For instance, this is how the Participants proxy asks the server to insert a new participant:

public function addParticipant(participant:Participant):void { ServiceGateway.GetConnection().call("ProjectParticipantsService.save", new Responder(onAddParticipantResult, onFault), participant.toDto()); }

On the server side, Google App Engine takes care of executing your application when it receives requests. The Python application uses PyAMF to decode the client requests and execute the service operation that is being called. The data that is transferred between the client and the server is stored in Data Transfer Objects (DTOs). Since both Python and Actionscript are dynamic languages, I didn’t declare formal type structures for these DTOs. They are just dynamic objects. The service operations use App Engine’s Datastore API to store and retrieve objects.

This is how the ProjectParticipants service executes the operation to insert a new participant:

def save(self, participant_dto): if hasattr(participant_dto, '_key') and participant_dto._key != None: return self.update(participant_dto) else: return self.insert(participant_dto) def insert(self, participant_dto): participant = ProjectParticipant() participant.project = Project.get(participant_dto.project_key) participant.name = participant_dto.name participant.put() return self.to_dto(participant)

Some of my previous posts have more details about how I built this application:

I’ve deployed this sample application to Google App Engine. You can interact with it using this URL:

http://fernando-correia.appspot.com/

Click on Edit projects to open the RIA client. If you refresh the homepage you should see the updates you made.

I hope this can help other people who want to learn some of these techniques and tools. Your feedback is most welcome.