Fernando Correia’s Weblog

August 23, 2008

Example of RIA in the cloud

Filed under: Software Development — Fernando Correia @ 12:34 pm
Tags: , , , , ,

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.

July 30, 2008

Flex client using PureMVC

Filed under: Software Development — Fernando Correia @ 8:42 pm
Tags: ,

Continuing my quest to build a Flex client to a Python service on Google App Engine, I decided to try converting my previous example from the Cairngorm framework to PureMVC.

I liked the PureMVC approach better. Its notification mechanism is very simple and powerful. The view components are quite independent from the rest of the application. And, best of all, the framework’s architect, Cliff Hall, has a clear vision that the framework must be kept simple, with few features. He also is very active on writing documentation, examples and answering user questions on the forums.

After reading all documentation and examples I could find, I set out to convert one of those examples to deal with my business entitites: projects.

I must warn that what I am showing here is an exploratory project and a work in progress. It doesn’t represent, by any stretch, the best practices. By documenting my journey I intend to help others that may follow, and also to get some feedback and help on better approaches.

This is what the application looks like:

Using PureMVC the application is structured around a Façade object that has a reference to a collection of Models, a collection of Views and a collection of Controllers. Like this:

The model uses a “proxy” class that has the responsability of managing model objects. The view uses “mediator” classes that have the responsability of connecting the view to the application without too much coupling. And the controller has commands that are invoked by the framework when certain notifications are raised.

It is a good architecture with low coupling, high cohesion and clear separation of responsabilities. It is also lightweight and more concerned on providing guidance and structure than on restricting what the programmer can do. Currently I am considering this my framework of choice for my Flex experiments.

My post is not about explaining how PureMVC works. The project website does it quite well already, at least for those who are willing to invest a few hours learning it. But I will show some snippets of code that may at least raise some curiosity:

This is how the projects list forwards the “New project” command:

private function onNew(event:Event):void
{
    var project:ProjectVO = new ProjectVO();
    sendNotification(ApplicationFacade.NEW_PROJECT, project);
}

This is how the project form prepares itself for entering a new project:

case ApplicationFacade.NEW_PROJECT:
    projectForm.project = note.getBody() as ProjectVO;
    projectForm.mode = ProjectForm.MODE_ADD;
    projectForm.code.setFocus();
    break;

When the user submits the new project, this is how the project form handles this event:

private function onAdd(event:Event):void
{
    var project:ProjectVO = projectForm.project;
    projectProxy.addItem(project);
    sendNotification(ApplicationFacade.PROJECT_ADDED, project);
    clearForm();
}

So, the view mediator, that is a kind of Supervising Controller, causes the model to update itself with the new project’s data. This method in the model’s proxy class is implemented like this:

public function addItem(item:Object):void
{
    Gateway().call("ProjectService.save", new Responder(onAddItemResult), item);
}

So, it talks directly to the service using a remote object gateway.

There is also a Participants list, but it is not persisted to the server yet. It is only kept in the client’s memory and goes away when the application is closed. I am still trying to figure out the better way of dealing with it.

I hope this helps. The project is published on github. Feedback is welcome.

The Rubric Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.