DreamFactory & Modus Create Case Study - Hubspot.net

nutritionistcornInternet and Web Development

Dec 14, 2013 (7 years and 10 months ago)


DreamFactory & Modus Create
Case Study
By Michael Schwartz
Modus Create
April 1, 2013
DreamFactory partnered with Modus Create to port and enhance an existing address
book application created by Modus Create to the new DreamFactory Services Platform
(DSP). The address book application is for both mobile devices and has a desktop
version for administration.
This document describes the process of porting the application, the DSP platform, and
the resulting application.
GitHub Repository
The Address Book for DSP is in a public GitHub repository:
. Developers may peruse the repository, check out
the code, modify the code. It is licensed under the MIT License.
Starting From a Solid Foundation
Modus Create
’s internal enterprise address book application called RoloDeux provided
a simple, yet powerful facility to access and manage employee contact information from
desktop computers or mobile devices.
The Ext JS-powered desktop web application was the management console, while the
mobile version, employing Sencha Touch 2 framework, was meant to be an access
point only. RoloDeux enjoyed a number of custom-built widgets on top of the base
libraries, including a custom ExtJS 4 component called Ext.ux.SchemaGrid. This
component handles the dynamic generation of ExtJS data store, grid column definitions,
form for creation and editing of records, and URLs for performing API requests to do
CRUD operations.
The back end sported a speedy and feature-rich
server connected to a MySQL
database. The Object-Relational Mapping (ORM) implementation allows database
tables to be defined as JavaScript objects. Extraneous JavaScript members in the field
definitions for a Schema (table) are ignored by the ORM. This allows the programmer
to associate more “interesting” information about the field that SQL syntax does not
allow. When you edit the Schema definitions, the ORM automatically manages the
queries to the database to alter the tables there accordingly.
We are about to show how this significant update to RoloDeux yielded minimum
refactoring and maximum benefit on both back and front end in order to create a new,
exciting product.
DreamFactory Address Book Project Goals
Modus Create teamed up with Dream Factory to implement and upgrade RoloDeux, the
Address Book application to run on the new Dream Factory Services Platform (DSP).
The application would demonstrate the use of the platform’s API, exercise that API as it
was being developed, and provide a working example application for Dream Factory to
distribute to developers to learn the platform.
The scope of the application was extended quite a bit to include the creation of contact
groups and the organization of contacts into one or more of these groups. The focus of
the project would be on the mobile implementations, including a new Tablet
implementation. The features of the desktop administrative application were enhanced
minimally to facilitate the mobile implementations. The mobile implementations were
enhanced to become fully functioning contact list management applications with the
ability to create, edit, delete groups, contacts, and contact information.
The application is to be served from the Services Platform. The intent is to show that
front end developers can
develop complex client-server applications
using the platform.
DreamFactory Services Platform Overview
The DreamFactory Services Platform (DSP) provides a comprehensive palette of
services for SQL Data, NoSQL Data, BLOB Storage, User Management, External
Integration, and Application Hosting. The services are available through a REST
interface that supports either JSON or XML documents. DreamFactory’s document
exchange architecture provides the perfect back end for low bandwidth but high
performance mobile applications written in either HTML5 or native client technologies
like iOS.
Developers who wish to use DSP sign up for an account at
. Once logged in, a DSP instance may be launched
from the user’s dashboard.
Once the instance has been created and launched, it must be activated.
After activating the DSP, you are asked to create an initial “system administrator
The administrator credentials are on a per DSP basis and do not have to be the same
as the ones used to create your account on
You have one main account to manage your DSP instances. Each DSP has its own
concept of administrator and other users and roles.
Once you have a DSP instance spun up, you can access its Launch Pad by clicking on
the name from the Dashboard screen.
You will have to log into the DSP’s Launch Pad using the administrator credentials you
created for it.
Upon successful login, you may administer the instance from the Launch Pad.
From the navigation menu on the left, you may create and manage one or more
applications, manage users and roles, manage services, and so on.
There is also live Swagger based documentation for the DSP Rest API. Here you can
read the documentation for the various methods and interactively try them out.
For the purposes of discussing the address book application, the screen shots show the
application already created and set up.
The database tables are managed using the “Manage Schema” interface. For the
address book, the JSON used to create the tables can be found in the schema/
The tables were created from the JSON in the GitHub repository using the “Import
JSON Schema” feature:
The JSON is simply copied into the textarea and the table is created by clicking on the
“Create Table” button. The JSON may later be modified and imported again to update
the existing table.
To deploy your application files on the WWW server, there’s a file manager that lets you
browse the directory structure of your deployed app and even edit the text files in your
browser. Click on the folder icon next to your application.
For a project like the address book, which includes both ExtJS 4 and Sencha Touch 2
libraries, and consisting of numerous client side script files, developing your project
through the file manager interface is not ideal. Developers like to use their preferred
programming tools and source code control systems; these things are not supported by
DSP yet.
Fortunately, the file manager provides an Upload File button that makes deploying an
entire project a snap! In the GitHub repository, there is a build.sh script that creates
a .zip file of the application’s files (df.zip). This .zip file can be deployed via the Launch
Pad’s Upload File feature.
Make sure to check the two checkboxes indicated. These assure the zip file is
unpacked and its contents entirely replaces the application deployed.
For the Address Book application, the .zip file is 19 MB. Via broadband cable modem
connection, it is uploaded, unpacked, and thus fully deployed in a minute or less.
Local Development
The address book application was developed originally on a iMac workstation and
GitHub for source code control. The DSP version was a fork of the GitHub repository
made into a new repository, and using the iMac and Apache for local development.
In the GitHub repository, there is an extras/ folder that contains a df-vhost.sample file.
This file contains the configuration for an Apache virtual host named “df” that uses
mod_proxy to implement a reverse proxy for the DSP API URLs. You will need to
merge this vhost configuration into your /etc/apache2/httpd.conf file and edit the
DocumentRoot path and the ProxyPass/ProxyPassReverse URLs are correct for your
file system and your DSP server.
You’ll have to add a line to your /etc/hosts file as well, for the df host: df
Now when you point your browser at
/ you will get the locally served HTML,
CSS, JavaScripts, images, etc.
There are two considerations when using this scheme for local development. First, the
URL and host for cookies set by your app will be df. If you log into the Launch Pad for
your DSP, you will have a different cookie set to show you’re logged in. You will have to
perform a login API call from your locally deployed version to access the rest of the API.
Second, URLs generated or used to access the Dream Factory API for your DSP will be
prefixed by “/service/” so they’ll be proxied to and from your DSP instance. Fortunately,
this is already done automatically by a common (between ExtJS and Sencha Touch)
common.DreamFactory API class.
DreamFactory API
The common.DreamFactory class can be found in the file docroot/common/
DreamFactory.js. It implements the Document Services REST API Version 0.6, roughly
as of February 28. This is a document provided by Dream Factory before launch of the
DSP service.
The common.DreamFactory class is used in both the mobile and desktop applications.
It is a singleton class, which means you can simply call its methods as needed. The
method names are consistent with the API call documentation. The methods
themselves are asynchronous in nature - they process function arguments, generate
API URLs accordingly, perform AJAX requests to the DSP instance, and then call an
application supplied callback method on completion.
For example, to login, you’d call:
common.DreamFactory.login(username, password, callback);
The callback function will be called with a JavaScript object consistent with the expected
response from the API call. In this case, a User object (see Users and Roles in the
Launch Pad) or an error indication.
The class determines if the code is running from a DSP instance and uses a direct URL
if so, otherwise it uses the /service/ prefix to use the Apache reverse proxy for local
In some cases, you will nest calls to the API methods within callbacks of other calls to
API methods. This would be the case for complex database interaction that require
multiple queries not directly supported by the DreamFactory API.
Application Structure
The address book application is structured as two distinct applications, desktop and
mobile, within its own directory structure but as a single application as far as the
deployment is concerned. As mentioned already, the common.DreamFactory class is
shared between the two.
The desktop version is a fairly traditional ExtJS 4 application. The mobile version is a
Sencha Touch 2 application that uses the profiles feature to implement both phone and
tablet presentations from a (mostly) single code base.
The application may be launched from the pull down menu on the DSP Launch Pad
page or by directly accessing the application’s URL from a browser or mobile device.
The index.html page for the Address Book application is only a simple JavaScript
program that detects whether browser is a mobile one or not. If it is, the browser is
redirected to the URL for mobile version of Address Book, otherwise it is redirected to
the URL for the desktop version.
Sencha Touch apps do not work well when run within iframes, so the redirect assures
the app is run in the top document. The desktop version will run in the Launch Pad’s
Upon application start (desktop and mobile), the SilkJS style JSON is loaded via an
AJAX request. The resulting Objects are used to drive the grids, forms, etc., for the
application. If the database Schema is changed, the JSON file needs to be edited to
reflect the change as well.
The desktop application can be found in the GitHub repository docroot/desktop
directory. The mobile application can be found in docroot/mobile.
Desktop Application
The desktop application features a tab panel, initially with Contacts and Groups tabs.
Within each tab is an ab.ux.SchemaGrid component. The SchemaGrid is driven off the
schemas JSON that is loaded at application start. One SchemaGrid presents records
for Contacts, another presents the Groups records. The Add, Edit, and Delete buttons
are managed by the SchemaGrid component. The Filter text field is a configurable
option to the SchemaGrid.
Selecting a record and clicking on the Edit button brings up the Edit Record dialog. The
fields in the form are driven from the JSON schema as well.
Of note here is the Groups field, which is a custom ExtJS component called
DataSourceField. There are tables of ContactGroups and Contacts in the database.
There is a ContactRelationships table that simply binds a Contact record to a
ContactGroup record. This structure allows for an arbitrary number of Contact records,
an arbitrary number of ContactGroup records, and an arbitrary number of associations
of Contacts to ContactGroups.
In order to represent the membership of a Contact in ContactGroups, the
DataSourceField renders all the Groups as Checkbox fields. Where there is a
ContactRelationship record binding the Contact to a ContactGroup, the Checkbox is
checked. The DataSource field works with two sets of values: the set of all possible
values and the set of selected values.
Submitting the form with the DataSourceField requires some extra work. The value of
the field is really a set of ContactRelationships records that need to exist in the
database after the Contact record is saved. It’s complicated by the fact that a
relationship may exist before the Contact is edited (checked) and the user unchecks the
Checkbox for the ContactGroup. So all existing ContactRelationship records for the
Contact are removed, then new ones added to reflect the selected Checkboxes.
Double clicking on a Contact record in the Contacts grid opens a new Tab where the
user can edit ContactInfo records associated with the Contact. The idea is that a
Contact may have multiple phone numbers, multiple email addresses, etc. The app
currently defines three types of ContactInfo: Work, Home, and Mobile.
The ContactInfo records are managed by SchemaGrid as well. The optional Filter text
field is not used here. The Tab containing the ContactInfo records grid is closable.
The mechanisms for maintaining ContactGroups are the same as for maintaining the
Contacts. The Groups Tab contains a SchemaGrid that enables CRUD operations on
the Groups records.
Deleting a ContactGroup record requires all the ContactRelationship records for that
ContactGroup to be deleted from the database. Similarly, deleting a Contact requires
the associated ContactRelationship records to be deleted from the database.
Mobile Application
The mobile application is mostly a single code base, using Sencha Touch’s profiles
feature to define code specific to running on a phone or tablet.
As with the desktop application, many of the forms and displays are driven from the
JSON schema that is loaded at startup.
While developing locally,
will load the mobile
application with the Phone profile into the browser.

will load the mobile application with the Tablet profile into the browser.
When running the application from the DSP instance, the device type is detected and
appropriate profile is automatically selected.
Google Chrome’s Developer Tools has a handy feature for developing for Phone and
Tablet configurations.
From the Developer Tools settings (gear icon in lower right corner), select Overrides.
On the form that is presented, you can select a User Agent and Device metrics. The
Device metrics shown is for iPhone in portrait orientation. The button to the right of the
width and height Screen resolution fields toggles between portrait and landscape.
Phone Profile
The user is initially presented with a credentials form. Any username and password he
enters is saved in local storage on the device and shown the next time the application is
run. The credentials used are for Users (and Roles) set up in the Launch Pad back end
for the DSP instance.
The initial screen shown after logging in is the ContactGroups list. This component is
shared between the Phone and Tablet profiles. The button in the upper right allows the
user to add a new ContactGroup.
Selecting a ContactGroup from the ContactGroups list reveals the Contacts list. This list
component is shared between the two profiles. The “All Contacts” group is not a true
group. It is not stored in the database or processed like the other groups. It is forced to
be the first group in the ContactGroups list. It allows the selection of all contacts, to be
shown, regardless of ContactGroup membership.
Entering text in the Search field filters the list as expected.
Selecting a Contact from the Contacts list reveals the Contact Details for the selected
contact. The Contact Details component is shared between the two profiles.
Tapping on the values of the fields does what makes sense for the type of field. Tapping
on the phone number dials the number. Tapping on the email address opens the mail
client to send mail. Tapping on the address opens the maps application to show the
From the Contact Details card, the Contact information can be edited.
To edit the ContactGroups memberships for a Contact, a mobile.ux.DataSourceField
component was created. It works similarly to the desktop implementation.
The interface for deleting ContactGroups and Contacts is via a leftward swipe on the list
display. That is, swipe left on the item to be deleted and a “Delete” button appears.
Tablet Profile
As with the Phone profile, the user is initially presented with a credentials form. Any
username and password he enters is saved in local storage on the device and shown
the next time the application is run. The credentials used are for Users (and Roles) set
up in the Launch Pad back end for the DSP instance.
After log in, the tablet layout of the mobile application is displayed.
The layout consists of two columns.
The left column is designed to navigate through the ContactGroups and Contacts. The
ContactGroup list component is on top and the Contact list component is below that.
The exact configuration of the “add” buttons and search box are appropriate for this
The right column is used to display and edit the selected Contact information.
Selecting a group from the ContactGroups list filters the Contacts list below.
Typing into the search box filters the Contacts list as well.
Selecting a Contact from the Contact list displays the Contact’s details on the right.
The Contact can be edited by tapping on the Edit button in the upper right corner.
The mobile DataSourceField is used in the Tablet profile as well.
Though the ContactGroups list, Contacts list, Contact editor form, etc. are common
between the Phone and Tablet profiles, there were some challenges to deal with for the
On the Phone, only one list, detail display, or editor is shown at a time. When you
navigate to a card, its contents can be refreshed with the latest data from the server.
For the Tablet, the user can interact with the ContactGroups list while the Contact editor
is shown on the right. Or the user can interact with the Contacts list.