Fernando Correia’s Weblog

August 13, 2008

Flex with GAE: adding participants to projects

Filed under: Software Development — Fernando Correia @ 9:45 pm
Tags: , ,

I’m making progress on my endeavor to build a Flex client to a Python service hosted on Google App Engine.

On the last iteration I had the whole architecture set up, using PureMVC on the client side and PyAMF on the service side. The application was able to show, create, edit and delete projects. It also handled project participants, but only in memory, without persisting them.

Now, the project participants are being persisted as Google App Engine model objects, referencing the project model objects.

This is the model definition on the server side:


class ProjectParticipant(db.Model):
    project = db.ReferenceProperty(Project, collection_name='participants')
    name = db.StringProperty()
    created_at = db.DateTimeProperty(auto_now_add=True)
    modified_at = db.DateTimeProperty(auto_now=True)

The service operations are implemented using a standard PyAMF RPC pattern (not REST yet):


class ProjectParticipantsService:
    def get(self, key):
        logging.debug('get %s' % (key))
        return self.to_dto(ProjectParticipant.get(key))

    def insert(self, participant_dto):
        logging.debug('insert %s' % (participant_dto))
        participant = ProjectParticipant()
        participant.project = Project.get(participant_dto.project_key)
        participant.name = participant_dto.name
        participant.put()
        return self.to_dto(participant)

I am using the anonymous DTO approach that I described in a previous article:


def to_dto(self, participant):
    if participant is None: return None
    dto = DTO()
    dto._key = str(participant.key())
    dto._id = participant.key().id()
    dto.project_key = str(participant.project.key())
    dto.name = participant.name
    dto.created_at = participant.created_at
    dto.modified_at = participant.modified_at
    return dto

On the client side I have a domain object representing a project participant:


[Bindable]
public class Participant
{
    public var _key:String;
    public var projectKey:String;
    public var name:String;
    public var created_at:Date;
    public var modified_at:Date;

    public static function fromDto(dto:Object = null):Participant
    {
        var participant:Participant = new Participant();
        participant._key = dto._key;
        participant.projectKey = dto.project_key;
        participant.name = dto.name;
        participant.created_at = dto.created_at;
        participant.modified_at = dto.modified_at;
        return participant;
    }

    public function toDto():Object
    {
        var dto:Object = new Object();
        dto._key = _key;
        dto.project_key = projectKey;
        dto.name = name;
        dto.modified_at = modified_at;
        return dto;
    }

    public function toString():String
    {
        return name;
    }
}

I also follow PureMVC’s approach of using proxy objects to manipulate the model objects, like this:


public class ParticipantsProxy extends Proxy
    {
        public function getProjectParticipants(projectKey:String):ArrayCollection
        {
            if (participants[projectKey] == undefined)
               participants[projectKey] = new ArrayCollection;
            return participants[projectKey] as ArrayCollection;
        }

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

        private function onAddParticipantResult(result:Object):void
        {
            var participant:Participant = Participant.fromDto(result);
            var projectParticipants:ArrayCollection = getProjectParticipants(participant.projectKey);
            projectParticipants.addItem(participant);
            sendNotification(ApplicationFacade.PARTICIPANT_ADDED, participant);
        }

        // (etc.)
    }

The rest is done on the View layer, like this:


private function onAddParticipant(event:Event):void
{
    var newParticipant:Participant = new Participant();
    newParticipant.projectKey = participantsPanel.project._key;
    newParticipant.name = StringUtil.trim(participantsPanel.newParticipant.text);
    participantsProxy.addParticipant(newParticipant);
    participantsPanel.newParticipant.text = "";
}

You can download and browse the source code through github. Feedback is welcome.

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: