Dynamic Flex Scaffolding for Grails via REST Services : Part 1: Getting the model out to Flex via REST services.

I’m building a mechanism to build dynamic CRUD scaffolding for Flex on Grails via REST services. In this post, I will outline the overall goals of this experiment, and document some of the progress I have made with serializing Grails domain classes out as XML.

Download

All the code of this experiment is open source and released under the Apache License 2.0. Once I have made enough progress, I will look into either integrating this into the Flex plugin or making it a standalone Grails plugin. You can download the work done via google code:

http://code.google.com/p/flexible-grails/

Overview

The goal of this experiment is to build a flexible way to build scaffolding that relies on client-side technologies rather than delegating the code generation to the server.

One of the nicer features of Flex is the ability to think of visual components as Object with data and states, and manipulate these via the ActionScript programming language. Flex components natively support XML via the e4x mechanism, and they are much easier to style and skin. The Adobe AIR technology allows access to Desktop components and is able to write files out to the filesystem.

So what if we moved some of the scaffold generation logic down to the client? Instead of using Groovy on the server side to write out ActionScript and MXML files, can we use ActionScript to build Scaffolding components. What would be the advantages of this approach?

Architecture

ideaSo there are a few pieces to this puzzle, but it is essentially a 2×2 grid. We need a way to get the structure of the data into the Flex Scaffold, and we need a way to pass the actual data being worked on into the scaffold to allow for CRUD functionality.

I’m using XML Rest Services as a transport layer between Grails and Flex. This seems like a good match. The XMLMarkupBuilder in Groovy is fantastic, and XML support in Flex is second to none. For this project, I’m writing a custom FlexScaffoldController that moves all the information in Grails Domain Class constraints and association information in a way that Flex can understand. This data is then used to dynamically generate client-side form elements and validators.

Transporting data is actually fairly straightforward, as it uses standard REST mechanisms to modify and submit data changes.

Since we are using XML, it would be possible to replace both the client or the server side component very easily. One of the advantages of this approach is that it works in parallel to the Grails server-side templating mechanism. By using the Content Negotiation feature in Grails, we don’t have to settle for one type of templating for editing data. Since templates are completely independent of the server, it would be possible to have different types of editors to make editing server side content easier. Views for the Palm Pre, iPhone, Air, Silverlight and other view technologies are possible, making this architecture more flexible than architectures that rely on closely bound technologies. Similarly, the server side components could be replaced by Rails, Pylon, Firewater, the expression engine or any other server technology capable of providing XML web services. However, this project does use the Grails template mechanism as a reference.

Getting Data Out – The FlexScaffoldController.

Enough yapping. Let’s get to the code. The FlexScaffoldController is a simple controller that serializes the information the lives inside Domain Class definitions and serves them out in a XML format.

I currently have only two actions here, domainClasses and define. DomainClasses serves as a list function for all the available domain classes, this is similar to the way index.gsp lists out all the available controllers.

Getting the list of Domain Classes

Grails

When I call http://localhost:8080/flexongrails/flexScaffold/domainObjects , I get a very simple list of all the domain objects available. The xml file looks like this:

<domainClasses>
   <domainClass name="News"/>
   <domainClass name="Video"/>
   <domainClass name="Price"/>
   <domainClass name="Color"/>
   <domainClass name="Product"/>
   <domainClass name="ProductVariation"/>
   <domainClass name="PressRelease"/>
   <domainClass name="Photo"/>
</domainClasses>

 

Nothing fancy here. Just a list of my domain objects.

Flex

I then build a simple Flex interface ( under the src/flex directory ) that uses REST services and e4x binding to render out a list selection mechanism:

simpleSelector
However, to show the versatility of using Flex as a display technology, I also built an alternate view to this model, the RandomFlickrImage view. Basically, it just takes the name of the domain class and does a “most interesting” search in Flickr, randomly choosing between the top 10 to generate an id. It looks like this.

FlickrView
Already, we can see how Flex allows us to build rich editing UIs with very few lines of code. ( Domain selector is 77 lines and the custom flickr renderer is 40 lines ).

Getting Domain Class Definitions – the define function

Make me a XML

One of the complaints that Tim Spurway, one of the best architects I worked with, had with platforms like Django, Pylon, Rails and Grails was how templates were always closely bound to the server technologies. Once you write out a view or a template, you are dealing with structured data, losing a great deal of flexibility. Changing templates would mean writing more server side templates for client side code. It didn’t seem intuitive since you’re dealing with text files, rather than an object model.

One of the ways to get around this restriction is to make the model definition just a structure, and then using the power of the client to generate the necessary templates. Essentially, instead of writing text files with another language that translate, use the end language to generate these components.

In this experiment, I looked at the key components of a domain Class definition and use the XmlMarkupBuilder to render out an xml of this representation.

Let’s take the Video.groovy file, it looks like this

class Video {
    String url
    static constraints={
        url( url:true )
    }
}

 

When you call http://localhost:8080/flexongrails/flexScaffold/define/Video , you will get the following XML:

<model name="Video">
     <properties>
           <property name="url" type="class java.lang.String" persistent="true" optional="false" association="false" bidirectional="false"
            associationType="" otherSide="" referencedDomainClass="" order="1" format="" inList="false" max="" size="" min="" minSize=""
            range="false" scale="" widget="" display="true" editable="true" nullable="false" password="false" creditCard="false" email="false"
            blank="false" url="true" matches=""/>
     </properties>
</model>

 

This might look like total and complete overkill, but this definition contains all possible associations and constraints available to Grails. With this definition, I have all the information I need to build the structure of my Flex Scaffold. Let’s go over some of the details.

Constraints

The property you see is basically a concatenation of the GrailsDefaultProperty class and the ConstrainedProperty class in Grails. We simply serialize all available attribute to a property out into a xml node called property. The sort order, as defined in the ConstrainedProperty class, dictates the sequence in which these items are shown. Rather than trying to sort two different classes in Grails, we will use the Flex XMLListCollection object to do so later.

If you take a look at my constraint test domain class called News ( http://localhost:8080/flexongrails/flexScaffold/define/News ), you will see some design decisions that I hope are not too terrible:

inList and Range constraints are listed as a child node to the property XML, this will hopefully allow for easy access for scaffold generation:

<property name="newsType" ...>
   <inListValues>
      <inListValue value="breaking"/>
      <inListValue value="amazing"/>
      <inListValue value="awesome"/>
   </inListValues>
</property>

 

Associations

Another important aspect of scaffold generation is knowing how domain classes are related to one another. Take a look at the ProductVariation domain class ( http://localhost:8080/flexongrails/flexScaffold/define/ProductVariation ), this sample domain class illustrates how relationship information is stored in the properties. This is actually just a facsimile of the current Grails mechanism.

<property name="trimColors" ... association="true" bidirectional="true" associationType="many-to-many" 
otherSide="products" referencedDomainClass="Color".../>

 

The information highlighted in red will allow us to reconstruct associations in the scaffolding. In my opinion, managing these relationships is perhaps one of the weakest aspects in Grails right now, and hopefully a Rich Internet Application alternative can allow more robust relationship management ( can you say drag-and-drop? ).

What’s Next?

Not bad for two days of work, huh? I’ll be moving to England to start a new job with Pixsta on Saturday, once I get settled, I hope to continue this work. Obviously all the scaffolding from the Grails end, and the actual passing of the data still has to be written.

But here are some of the more interesting ideas I have for this project going forward:

  • Use Adobe AIR to generate the ‘static’ scaffolding version of the dynamic scaffold.
  • Have a switch that will allow the scaffold to generate a BlazeDS / AMF / Flex plugin type template.
  • Explore the multiple technologies idea by building a simple iPhone / Objective-C scaffold using the SeismicXML example as the source.
  • Demonstrate Drag and Drop editing with an AIR image upload alternate view.
  • Explore the use of the AIR HTML component for live previews.

Stay tuned for the next installment.

2 thoughts on “Dynamic Flex Scaffolding for Grails via REST Services : Part 1: Getting the model out to Flex via REST services.

  1. Michael Walker

    A very promising start. I will watch this closely…
    Thomas, I would love to be able to assist but I am flat out trying to deliver a major project. I will chip in whenever I can.

    I suggest you keep things as generic as possible for maximum usage. E.g. from the Grails side there is no need to use any reference to “Flex”: you are creating a controller that exposes Grails domains metadata. Other consumers may find this useful in and of itself?

    Best of speed with this.

    Michael Walker

    Reply

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