Situational applications have been defined as "...software created for a small group of users with specific needs."
Well, there was a situation at home...
An elaborate set of built-in bookshelves that housed hundreds of books needed to be repainted. With all the books cleared off the shelves so the job could be done, it seemed a good time to reorganize them all and create a cataloging system that would give us better access to information about what books we owned, and about specific details about those books. The catalog system would help us determine if we had duplicate books and even help us identify books we didn't know we had. In short, we had a situation that needed an application. What a perfect opportunity to put IBM WebSphere sMash through its paces.
Developing a situational application in sMash
Before you get started, this article assumes that you have WebSphere sMash (or Project Zero, which is the community development implementation of WebSphere sMash) installed on your machine. It's very simple to download and install, and there are two versions available:
- WebSphere sMash Developer Edition (DE)
- The latest build of Project Zero, named Silverstone.
Either version should work just fine, but the M2 (milestone 2) version of Silverstone was used as the basis for this article.
There are at least two ways you can build a sMash application. One is to use the Eclipse plug-in for sMash. Another is to use the nifty Web-based Application Builder (AppBuilder) that comes with sMash. Both of these environments have merit and value, so it is really a matter preference. This exercise uses the Web-based AppBuilder that is included with sMash.
The easiest way to get your application up and running quickly is to use the Zero Resource Model (ZRM), which provides a very simple way to create a datastore and provide RESTful handlers for that datastore.
To create the datastore you only have to create a model for it: a JSON file that defines the fields and options for those fields. The model is used to create the datastore, and it's the one source of all metadata information about the datastore. ZRM is typically used for green field applications, which are applications that don't have legacy data sources.
Let's define a simple model for your card catalog. Those among you who are more skilled in the library sciences might frown upon the naïve field set in the model. Fair enough, but keep in mind that this is a situational application and that the goal is to get something up quickly that meets your needs.
-
Start AppBuilder
-
Begin by starting up the AppBuilder. From the command line run the
appbuildercommand. This command has changed over time, so depending on which version of sMash you're working with, you will need to adjust what you type. This applies to both Windows® and Linux®. There are scripts (batch files) for both of these operating systems and they generally run great. However, if you're having difficulty, take a look at your environment variables. You need to have Java™ and the zero directory in your path, and your JAVA_HOME environment variable must be set to the same Java as the one in your path. (One of the authors is blushing from making that mistake.) In the M2 version, if you only typeappbuilder, you'll see a list of parameters which you can pass to the script (Figure 1).
Figure 1. AppBuilder script parameters
-
Once you've started up AppBuilder, you should see a message in your command window that says something similar to that shown in Figure 2.
Figure 2. AppBuilder successful start
This was obviously done from a Windows command line, but the same should occur on Linux as well. If you have Firefox installed, the AppBuilder Welcome panel (Figure 3) if this is your first time using AppBuilder. If you don't have Firefox installed, then enter the URL from the command window, http://localhost:8070, into your browser.
Figure 3. AppBuilder Welcome panel
If you see a AppBuilder panel other than the Welcome screen, don't fret. This just means you've probably playing with AppBuilder already.
AppBuilder is typically run locally on your machine. There are forum postings on projectzero.org that discuss how you might run AppBuilder on a server if you need that sort of configuration, but this is beyond the scope of this article.
-
-
Create the application
-
Designed for ease of use, AppBuilder outlines for you the simple three step process for building an application right there on the Welcome panel (Figure 4).
Figure 4. Create an application
Go ahead and perform those steps, first by clicking the Create new application link in the green Actions box on the left (Figure 5).
Figure 5. AppBuilder Actions
-
On the Create new application dialog (Figure 6), enter or select the appropriate values for all fields and then click the Create button. In Figure 6, you see the choices we made (our Application name is "CardCatalog"), but feel free to use (and remember) your own values.
Figure 6. Create new application
-
You should now see a listing of all the applications you have created or brought into the AppBuilder. In Figure 7, the only application we have is our new CardCatalog library application. Find your CardCatalog application and click the title.
Figure 7. Application list
This puts you into your application project space. You are now ready to create resources, templates, models, and so on, for your application.
-
-
Build the data model
-
When you begin building the data model definition for your application, an informational help page is initially displayed (Figure 8). This page will get you started whether you are creating a new file or editing an existing one. For this exercise, you will create a new file by pressing the New File link in the green Recent Files box.
Figure 8. Build the data model
-
A dropdown box displays several different file paths for you to choose from (Figure 9). Since you are going to create a data model, select Zero Resource Model in /app/models from the list for your new model definition.
Figure 9. File path choices
-
The File Create dialog lets you choose your model definition file name, "books" in this example.
Figure 10. File Create dialog
The name of the definition file is important since, by convention, it will be used for the name of the resource. In other words, you will call this resource using this URL: http://localhost:8080/resources/books. The name is also the Type name and all instances of that Type must conform to the constraints given by the definition.
Enter a name and press the Create button.
-
The Missing Dependency displays (Figure 11).
Figure 11. Missing Dependency dialog
Go ahead and press the Add button. This will automatically add the zero.resource dependency to your ivy.xml file:
<dependency name="zero.resource" org="zero" rev="[1.0.0.0, 2.0.0.0["/>Essentially, this dependency tells WebSphere sMash that you intend to use ZRM in this application, and so in return, WebSphere sMash creates a condition that enables you to use ZRM.
-
The books.json file should now be open for editing -- but first, go click the ivy.xml file in the left column and you'll see that the zero.resource dependency has been added. Optionally, you can click on the Dependencies tab to verify that the dependency has been added, as shown at the bottom of Figure 12.
Figure 12. Application Dependencies tab
If the zero.resource dependency is missing, then you need to add it to the ivy.xml file, either by directly editing the file, or by using dependency panel above (Figure 11).
-
Open books.json. The user interface for editing models has changed over time. Figure 13 shows the M2 version, which lets you add fields graphically in the editor.
Figure 13. Model editor
For each of your fields, click the String button to add a new string value, then press the
button to open up the
field property editor. Enter a value for the field name in the Basic tab and the field size in
the Advanced tab. The default field size is 50 characters which isn't
large enough for many fields. Enter these values for your field names and
sizes:name, 512author, 512description, 1024isbn, 17
If you want to take a look under the covers, click the Explorer tab and navigate to the file so you can view it. You should see something similar to Listing 1.
Listing 1{ "collections": { }, "fields": { "name": {"label": "", "required": false, "type": "string", "description": "", "default_value": "", "max_length": 512 }, "author": {"label": "", "required": false"type": "string", "description": "", "default_value": "", "max_length": 512 }, "description": {"label": "","required": false,"type": "string", "description": "", "default_value": "", "max_length": 1024 }, "isbn": {"label": "", "required": false, "type": "string", "description": "", "default_value": "", "max_length": 17 } } }
If your version of WebSphere sMash doesn't feature the nifty GUI editor (Figure 13), you can add the above JSON code to the books.json file to create the model.
You can, of course, add or change fields as you'd like, but let's take a look at what we have in this code:
- The fields element is a necessary part of the model definition, so there's not really much to say other than it needs to be there.
- Each field is then named in turn and each represents a database field.
- Each of these fields is further qualified with, minimally, a type.
- We have added a bit of further metadata to define the max_length of each string: the default max_length is 50 characters, so you will need to set this for nearly every string field.
- Other than the fields you have explicitly identified, two other fields
will get automatically created for you:
- The id field, an integer that starts at 100 and is automatically incremented, is created as a unique identifier for this instance of the data.
- The updated field contains the timestamp of the last update made to the instance.
-
-
Synchronize the data model
You can now synchronize the model, which generates and executes the necessary SQL to create the database. You can do this from the command line or from within the AppBuilder itself. Regardless of the method, the command that gets issued is
zero model syncand the output is the same. Using the AppBuilder:Click the Console tab on the top, then click the Command Prompt link in the left navigation bar.
Enter
zero model syncinto the Enter a zero command text field, then click the green Enter button. Your output should be similar to Listing 2.
Listing 2Available commands: zero,svn,clear,help * Commands are run from the current application root directory. command> zero model sync CWPZC9225I: Using default Derby database configuration. Located at -> db/resource in application root. CWPZC9223I: Found 1 model types CWPZC9212I: Created table -> BOOKS for Type -> books using SQL -> CREATE TABLE books ( name VARCHAR(512), author VARCHAR(512), description VARCHAR(1024), isbn VARCHAR(17), id INTEGER PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 100, INCREMENT BY 1) NOT NULL, updated TIMESTAMP NOT NULL ) CWPZT0600I: Command model sync was successful
You have just successfully created an empty model. Pat yourself on the back!
-
Add data to the model
You now need to put some data into your model so that you'll have something to look at when you run your application. To do this, you need to create load files in the app/models/fixtures directory. These data files are again JSON files, like the Resource Model definition files, and they contain objects to be loaded into the model. What makes these files different is that they might contain data from several different Resource Model types. In other words, if you also had an "authors" model, then these files could contain data for both the "books" model and the "authors" model.
-
To create a data file to load data into your model, click the New File link again in the Recent Files box and then select Other File (Figure 14).
Figure 14. Create data file
-
The File Create dialog will display again (Figure 10). Fill in the path and the file name for the data file you wish to create. In this example, the path will be
/app/models/fixturesand file will be calledload.json. In the file, you will enter data for two books, shown in Listing 3, just to get the library started.
Listing 3[ { "type": "books", "fields": { "name": "Programming Portlets", "author": "Ron Lynn, Joey Bernal, Peter Blinstrubas, Usman Memon, Cayce Marston, Tim Hanis, Varad Ramamoorthy, and Stephan Hepper", "description": "Shameless plug", "isbn": "978-1-931182-28-7" } }, { "type": "books", "fields": { "name": "The Pragmatic Programmer", "author": "Andrew Hunt and David Thomas", "description": "Good stuff", "isbn": "0-201-61622-X" } } ]
-
Any data file placed in the app/models/fixtures directory can be loaded into the model by running the
zero model loaddata <filename>command, so, again, go to the command line or the AppBuilder console to run this command:command> zero model loaddata load.jsonRegardless of how you run the command, you should see a message similar to that shown in Listing 4, which indicates success of the load.
Listing 4command> zero model loaddata load.json CWPZC9225I: Using default Derby database configuration. Located at -> db/resource in application root. File -> C:\zero\CardCatalog\app\models\fixtures\load.json CWPZC9214I: Created member Type -> books Data -> {description=Shameless plug, isbn=978-1-931182-28-7, name=Programming Portlets, author=Ron Lynn, Joey Bernal, Peter Blinstrubas, Usman Memon, Cayce Marston, Tim Hanis, Varad Ramamoorthy, and Stephan Hepper} CWPZC9214I: Created member Type -> books Data -> {description=Good stuff, isbn=0-201-61622-X, name=The Pragmatic Programmer, author=Andrew Hunt and David Thomas} CWPZT0600I: Command model loaddata was successful
-
If you had or wanted to create bootstrap data (data that you always wanted in a newly created model), you could create a file named initial_data.json in the app/models/fixtures directory. This special data file gets loaded whenever your database is created or recreated, eliminating the load data step above. Other than initial_data.json getting loaded for you automatically, there's no difference between it and other data files. This is a handy feature and time saver when you're developing applications using ZRM.
Once the data is loaded, you can test it out. But before you do that, this is a good time for a little reality check.
-
-
Iterate the model design
In our experience, you usually end up iterating over the data model design several times over the course of a project before you get it right. Therefore, we would like to call your attention to a couple of features that can make this process less painful, if not truly joyful.
You can run the
zero model synccommand whenever you like. Any models that have been previously created will be left alone and new models will be created. Even if you change a model, the sync will not affect the models already created.For example, suppose you want to add a field to your "books" model for notes. You would simply edit the model and add the field. This is done easily in the GUI editor the same way you added fields earlier. Simply add a
notesfield and set the size to 1024. Another option is to edit the file as shown in Listing 5.
Listing 5{ "fields" : { "name": {"type": "string", "max_length": 512}, "author": {"type": "string", "max_length": 512}, "description": {"type": "string", "max_length": 1024}, "isbn": {"type": "string", "max_length": 17}, "notes": {"type": "string", "max_length": 1024} } }
Now when you run
zero model sync, you see that no change has been made because the model already exists (Listing 6).
Listing 6command> zero model sync CWPZC9225I: Using default Derby database configuration. Located at -> db/resource in application root. CWPZC9223I: Found 1 model types CWPZC9224I: Type -> books already created with table name -> books CWPZT0600I: Command model sync was successful
The sync command will not change an existing model. In order for the model change to take affect, you must run the zero model reset command, which drops the table and recreates it (Listing 7).
Listing 7command> zero model reset CWPZC9225I: Using default Derby database configuration. Located at -> db/resource in application root. CWPZC9223I: Found 1 model types CWPZC9215I: Executed SQL -> DROP TABLE books CWPZC9212I: Created table -> BOOKS for Type -> books using SQL -> CREATE TABLE books ( name VARCHAR(512), author VARCHAR(512), description VARCHAR(1024), isbn VARCHAR(17), notes VARCHAR(1024), id INTEGER PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 100, INCREMENT BY 1) NOT NULL, updated TIMESTAMP NOT NULL ) CWPZT0600I: Command model reset was successful
If this article was a session at a conference, a dozen hands would be raised at this point with the same question: "What about the data in the table?" To which I would respond, "It's dropped, gone, removed." Then, another dozen hands would come up with questions like, "What if I need to keep that data?" No problem, WebSphere sMash has you covered.
Actually there are two separate ways to keep your data, depending on your level of SQL knowledge. The first method is to use zero.data to directly update your database tables; this is beyond the scope of this article and so I refer you to the documentation on the Project Zero web site.
The second method is to dump the data to a file, change the model, reset the model, and then load the dumped data back into the new model:
-
Dumping the data is quite easy when issuing the
zero model dumpdatacommand:command> zero model dumpdata app/models/fixtures/exported.json
CWPZT0600I: Command model dumpdata was successful -
Next, update the model to reflect the changes. In this case, just add a new date field called "published," then issue the
zero model resetcommand (Listing 8).
Listing 8command> zero model reset CWPZC9225I: Using default Derby database configuration. Located at -> db/resource in application root. CWPZC9223I: Found 1 model types CWPZC9215I: Executed SQL -> DROP TABLE books CWPZC9212I: Created table -> BOOKS for Type -> books using SQL -> CREATE TABLE books ( name VARCHAR(512), author VARCHAR(512), description VARCHAR(1024), isbn VARCHAR(17), notes VARCHAR(1024), published DATE, id INTEGER PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 100, INCREMENT BY 1) NOT NULL, updated TIMESTAMP NOT NULL ) CWPZT0600I: Command model reset was successful
-
Notice that you now have a "published" field available. With this completed, reload the exported data the same way you loaded data previously by using the
zero model loaddatacommand (Listing 9).
Listing 9command> zero model loaddata exported.json CWPZC9225I: Using default Derby database configuration. Located at -> db/resource in application root. File -> C:\zero\CardCatalog\app\models\fixtures\exported.json CWPZC9214I: Created member Type -> books Data -> {notes=null, description=Shameless plug, isbn=978-1-931182-28-7, updated=2008-10-03 10:20:15, name=Programming Portlets, id=100, author=Ron Lynn, Joey Bernal, Peter Blinstrubas, Usman Memon, Cayce Marston, Tim Hanis, Varad Ramamoorthy, and Stephan Hepper} CWPZC9214I: Created member Type -> books Data -> {notes=null, description=Good stuff, isbn=0-201-61622-X, updated=2008-10-03 10:20:15, name=The Pragmatic Programmer, id=101, author=Andrew Hunt and David Thomas} CWPZT0600I: Command model loaddata was successful
Your model is now updated and your data has been preserved. You would still have to fill in the data fields, since your data did not previously contain values.
Next, let's look at how you can quickly and easily expose your new data model as a RESTful service.
-
ZRM has a wonderfully simply way to expose your model as a RESTful service. You need only write a single line of code and your data model will be exposed.
-
Return to the File Editor (Figure 14) and create a New File, this time a Resource Handler in /app/resources. Since your model is called "books," you should name the handler the same (Figure 15).
Figure 15. Create a resource handler
-
When the editor displays, enter this line of code into the books.groovy file, removing any others that might exist:
ZRM.delegate()This single call is all that you need to expose your data model as a service.
-
Let’s start up the application and see what it can do. Click the Start link that appears beside the green arrow icon in the upper right corner of the AppBuilder (Figure 16). (You will also notice a URL and port number right next to the start button. You’ll need that when you test your service next.)
Figure 16. Start the application
You can tell that your application is started when the Start button changes to a Stop button.
One very nice thing about WebSphere sMash is that changes take place automatically in the started application, so there is no need to stop and start after you make changes to code or anything. When the application is started, you can test your service to see what you can do with it.
Let's look at two ways you can test your RESTful service’s list, create, update and delete functions. The first method is to use a tool like Poster, a Firefox add-on that enables you to issue RESTful calls and see the returned JSON objects. This is very useful to a RESTful service developer. The second method is using the WebSphere sMash Dojo datagrid widget to add a simple user interface to your service.
This is a cool tool and gets down to the nitty gritty of the communication between the client and the RESTful service, but it’s not very user friendly.
Poster is a Firefox add-on that lets you explore and test a RESTful service outside of any Web-based GUI. After you have downloaded Poster (see Resources):
-
Open up Poster. Hint: When Poster is installed, a little "P" icon displays at the bottom of the Firefox window. Click the icon to open the tool.
-
Enter this URL into Poster, substituting whichever host and port number you see in the upper right hand corner of the AppBuilder:
http://localhost:8080/resources/books. -
Press the GO button beside the GET action (Figure 17).
Figure 17. Run Poster
Poster sends the request to your newly created service and returns the complete list of books in your database (Figure 18).
Figure 18. Poster response
There are many things you can do with Poster to exercise your service:
- You can retrieve books by id with URLs like this:
http://localhost:8080/resources/books/100
which will retrieve the book with id = 100. - You can filter your request based on fields such as:
http://localhost:8080/resources/books?name__startswith=Programming
orhttp://localhost:8080/resources/books?name__contains=Port.
These filters can be used on any field in your model. For a full list of filtering parameters, take a look at zero resource filter conditions on projectzero.org. - You can also create new data this way. You simply need to return to your
original list URL:
http://localhost:8080/resources/books.
- You can retrieve books by id with URLs like this:
-
Set the content type to
application/json, set the action to the POST method, and set the content to send the data in Listing 10.
Listing 10{“name”:”Dojo: The Definitive Guide”,”author” :”Matthew A. Russell”, ”description”:”“,”isbn”:”978-0-596-51648-2”, ”notes”:”Loaned to Kevin”}
Figure 19 shows what this should look like.
Figure 19. Create new data
Once you press the GO button beside the POST action, you will see a response like the one shown in Figure 20.
Figure 20. Post response
-
If you list the books again, you’ll see your new book in the list (Figure 21).
Figure 21. New data displays
Whoops! I must have hit the GO button a couple of times, because the new book displays twice in the results in Figure 21. Actually, this is a fortuitous accident, since we can take a look at how to delete a record from the service.
-
You’ll notice in Figure 21 that records with id values of 102 and 103 are duplicate records of the book you just entered. To delete the book with the id of 103, you would simply set the URL to point to item 103, change the method to DELETE, then press GO again (Figure 22). You should get a 200 response code if it succeeds.
Figure 22. Delete a record
The only other bit of LCRUD to look at is an update. You perform updates by using the PUT action. In this case, you want to update the book you just entered because "Kevin" returned it after reading this part of the article. To do this, you again point the URL at the particular book you want to update, set the content type to
application/json, the action to PUT, and send the content that you want to update (Figure 23).
Figure 23. Update data
Notice that you need to send all the fields or else you will end up clearing some data.
To use the user-friendlier datagrid Dojo component:
-
Start by adding Dojo to your project. Go to the Dependencies tab and click Add. Find the zero.dojo module, select it, and click Add (Figure 24). You will see that zero.dojo is now one of the dependencies.
Figure 24. Dependencies
-
Next, create a new HTML page in the /public directory and name it
datagrid.htmlwith the content shown in Listing 11.
Listing 11<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Testing with the Datagrid</title> <script type="text/javascript" src="/dojo/dojo.js" djConfig="parseOnLoad: true"></script> <script type="text/javascript"> dojo.require("dojo.parser"); dojo.require("zero.resource.DataStore"); dojo.require("zero.grid.DataGrid"); </script> <style type="text/css"> @import "/dijit/themes/soria/soria.css"; @import "/dojo/resources/dojo.css"; @import "/zero/grid/DataGrid/DataGrid.css"; @import "/dojox/grid/_grid/Grid.css"; @import "/dojox/grid/_grid/soriaGrid.css"; </style> </head> <body class="soria"> <!-- DataStore instance --> <div dojoType="zero.resource.DataStore" jsId="bookstore" contextRoot="" resourceCollection="books"></div> <!-- DataGrid instance --> <div dojoType="zero.grid.DataGrid" id="datagrid" store="bookstore" style="width: 600px; height: 300px;"></div> </body> </html>
-
Once this is done, and assuming you haven’t shut down the server, enter this URL into a new browser:
http://localhost:8080/datagrid.html. In return, you should receive a complete list of all the books in your database. Easy!
This datagrid has various functions to assist you in LCRUD operations. This little example should give you a basic idea about how you could use your RESTful service as a datastore with built-in Dojo wigets, or for your own custom Dojo widgets. With this as a starter, you should be well on your way to creating dynamic user interfaces that interact with RESTful services.
This article explained how to construct your own simple cataloging system using WebSphere sMash to create a dynamic user interface and a REpresentational State Transfer (RESTful) interface to a Derby database of books. Through this exercise, you learned how you can perform the typical list, create, retrieve, update, and delete (LCRUD) operations, but most of all we hope you have as much fun playing with this new software product as we had putting this example together.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample application files | CardCatalog-1.0.0.zip | 100 KB | HTTP |
Information about download methods
Learn
Get products and technologies
-
Download WebSphere sMash
Developer Edition
-
Download
Project Zero: Silverstone
-
Download Poster for Firefox
-
Groovy

Kevin Dzwonchyk is a Advisory Software Engineer for IBM as a member of IBM Software Services, servicing the IBM Global Account. He has been with IBM since 1997 working in support and services and development for IBM software products, focusing on WebSphere products. He is currently driving Web 2.0 innovation utilizing Groovy and PHP scripting on the sMash platform. He has an active interest in innovation utilizing cutting-edge products and concepts.

Ron Lynn is a Senior Software Engineer in the IBM Web Enablement and support team. He works from a small farm in the San Joaquin Valley of central California. Ron is currently working on internal portal projects that focus on giving more visibility to IBM's partner applications. He has written and spoken on portlet development and other topics numerous times and is co-author of the book Programming Portlets.




