Flex’s Data Transfer Pattern (Class Adapters)
We have been having several discussions at MediaRAIN recently about how we should handle data adaptation from the back-end to the Flex front-end. In most cases, our back-end devs are using CakePHP which bases the object model off of the database schema. In many of our projects, we found the Flex front-end guys going back and forth with the back-end guys about who should bear the brunt of adapting data stored in the database to the Flex front-end model.
The biggest drawbacks to this approach are that CakePHP does not intrinsically allow the develop to take fields from the database and convert them to a Flex front-end model. In order to force CakePHP to comply, there is an extra layer that has to be forced into the framework in an unnatural way. Normally, this hasn’t been a big deal when working with back-end Java solutions as object modeling straight out of the database is a common practice (although Hibernate may have similar problems as CakePHP). With my background in Java, and my lack of CakePHP understanding, I find it difficult to understand where the CakePHP devs are coming from.
There are many other benefits as well as drawbacks to modeling on the back-end in a CakePHP environment that have been carefully outlined in Aaron Hardy’s blog post entitled: The Why, What, and Where of Custom AMF Class Adapters. I have made a few comments as well as some of the other developers at MediaRAIN. Here are some of the key points from this awesome article:
Pros
- lack of high coupling
- less of a chance of refactoring due to database schema changes
- Decreases SWF size due to an absense of Adapter classes on the front-end
- Reduces the need to recompile the SWF due to back-end changes (especially handy in AIR when updates need to be sent out).
- Utilizes more of the server’s juice than the client’s computer (could also be a con depending on the circumstance, but I feel that in the majority of circumstances you can choose to upgrade your server speed, but you are at the mercy of the client’s computer speed.)
- Maintains the Flex front-end coding conventions and styles (i.e. first_name in PHP, firstName in Flex)
- Maintains the Flex standard of server communication: the Data Transfer Object pattern
- You can take advantage of AMF’s object mapping abilities to automatically cast the correct Data Transfer Object in PHP to it’s Flex equivalent without traversing Object hierarchys or Arrays.
Cons
- Back-end dev may need to twist the arm of the CakePHP (or Hibernate) framework to get it to include a back-end class adapter.
- By adapting classes on the front-end, a single back-end API can have the ability to serve multiple front-end clients due to its abstract nature, as opposed to a back-end closely tied to one particular front-end implementation.
In short, my feeling is that Data Transfer Objects should be implemented on the server-side and that any departure from this methodology should be the exception rather than the rule. There is a reason why Adobe supports it and why it is used in Cairngorm, Nimbus, PureMVC, and other Flex frameworks and by countless Flex developers throughout the world. Keeping in mind that every good answer seems to involve the words “It depends”, I am forced to not give a concise simple answer, because it really does depend on your implementation.
I’m sure there are plenty of other pros and cons that I am missing, or if anyone would like to comment on this discussion, please do!
I have to disagree. If any bending needs to be done it should happen on the front end. This offloads the work to the client, which we all know is a nice benefit of the flex/flash platform.
As the developer of CakeAMF, I made this decision a while ago. To compensate on the front-end I have been working on a sister project called Fake, which makes working with Cake objects in a native Flex environment trivial.
In fact, Fake uses a single model as the VO and RO which to me simplifies development in Flex even further.
Now onto your pros:
“lack of high coupling” – you are dreaming here. There is still a high degree of coupling no matter what you do.
“less of a chance of refactoring” – Any time you make a schema change you are going to need to update both ends. Really no way around it if you want to maintain strong typing.
“decrease swf size” – we are talking bytes here, not MB. Flex used to add 400kb and we still used it so really this pro is weak.
“utilize the server” – ALWAYS a con. simple as that.
“maintains style” – you can still have that if your resultset class formats things the way you want.
“maintains flex standard” – the most valid pro, but really is that a good standard we should even follow?
“take adavantage of object mapping” – you can still have this, as we do in Fake.
The Cons are both valid and are actually big Pros that outweigh the Cons when you decide to push the job onto the front end.
Anyway, its a good question for discussion. I hope i have added to it.
Good Luck.
Fake is currently located on google code:
http://fake-as3.googlecode.com
There are some examples and also test cases for how the as3 conversion is done via the ResultSet class.
A few of us hang out in #fake-as3 on irc.freenode.net
Bottom line, Coupling is no fun and has to be dealt with. You are not avoiding it by using a DTO.
As far as the server goes, You hit the nail on the head. Conversion is light and therefore will have very little if any noticeable affect on the client. Whereas, if you do it on the server, for a couple hundred users, I am sure you will notice it. Of course, you could cache, but that just creates more work and potential for problems.
For me the biggest thing is having the same controllers for amf, xml, json, html, without the need for extra logic.
@gwoo
You have some good points. Here are my responses to your arguments…
1. High Coupling. As for your arguments, first when I say high coupling, I am referring to coupling between the front-end and back-end. If there are multiple front-end solutions that use the same CakePHP backend, then for every change that is made to the database an overhaul will ripple out to the front-end implementations. For Flex applications, this means that you need to rebuild (and redistribute) the SWF. In AIR applications, this is even more problematic as it would require an update to be pushed out to every installed AIR application.
If the modeling due to the database change were handled on the backend, this wouldn’t have to happen. In my opinion, this is not a good thing. However, the same can be said if your front-end application has several different back-end implementations. I think this is less frequently used, hence my reasoning for doing it on the back-end.
2. Less of a chance of refactoring. I agree with you that schema changes in the database will more often than not require a change to the front-end. However, what if you decide that the schema you are using for the backend is inefficient for some reason. Maybe you are using too many joins, or your back-end is overly taxed? This might be a reason to refactor that database schema which would require you to change the front-end and rebuild. If all of this were handled on the back-end, we wouldn’t have to deal with the front-end in these cases.
3. SWF Size. True, SWF size isn’t that big of a deal since the object modeling classes wouldn’t add too much overhead, but I feel it is a matter of principle that you should always try to keep the size down.
4. Utilize the server. You can always add server space and computer power as you see fit. This part can be perfectly scalable (according to your budget). The client’s computer, on the other hand, you have no control over. This is probably not that big of a deal because the computing power required to model objects is probably negligible.
As a side note, I would be interested in hearing your ideas for Fake. If this is something you could share, let me know.
Thanks for your thoughts.
I will be checking that out. In fact, maybe I’ll write a post about it once I try it out. Thanks.