Using the Zero Resource Model for database management in WebSphere sMash

The article offers details and insight into features and capabilities of the Zero Resource Model for database management on the IBM® WebSphere® sMash platform. This peek at agile database management describes the built-in database handling and processing capabilities of WebSphere sMash, and provides code samples that can serve as a starting point for application developers. This content is part of the IBM WebSphere Developer Technical Journal.

Share:

Arun Lobo (arulobo1@in.ibm.com), Software Developer, IBM

Arun Lobo is a software developer and a working member of Web 2.0 and Mobile feature pack team at IBM India Software labs. He has also worked on Web 2.0 and Java EE technologies apart from appliance firmware and server technologies.



14 March 2012

Also available in Chinese Russian

Introduction

Database management is essential for a wide range of situational applications, for which the IBM WebSphere sMash platform was tailor made. WebSphere sMash has always had good support when it comes to databases. You can connect to a datasource externally via a JDBC bridge, or you can use the built-in support of embedded Derby databases. But to make database management easier and simplified, WebSphere sMash uses a resource model known as Zero Resource Model. This article explains the Zero Resource Model and provides some examples to help you begin using it.

Although some introductory material is presented here, this article assumes general familiarity with the IBM WebSphere sMash platform and related concepts in order to focus on the Zero Resource Modela as a versatile, agile alternative to existing means of database management.


Database management in WebSphere sMash

IBM WebSphere sMash is a development and execution platform for quickly building agile, web-based applications. In all, it is:

  • A platform for building and developing applications.
  • A server on which to deploy applications.
  • A run time environment.

WebSphere sMash runs on the Java™ platform.

Web applications in WebSphere sMash are developed using one of two scripting languages: Groovy or PHP. Groovy is a scripting language designed specifically for the Java platform. It is syntactically similar to the Java programming language, but is semantically less strict and a more free form variation of the language. Web applications in WebSphere sMash are written as per the REST principle by implementing a handful of REST methods. PHP is an alternate language for scripting, but for the purpose of this article, all code examples shown here are in Groovy, unless stated otherwise.

By default, WebSphere sMash provides support for databases through JDBC and other well known methods. In addition, WebSphere sMash also comes with an embedded Derby database. You can connect to this database through common means (such as an ODBC/JDBC bridge) and you can carry transactions using SQL queries. Alternatively, you can use the pre-defined API-rich Zero Resource Model.

The Zero Resource Model (ZRM) provides a simplified way to create RESTful resource handlers (explained later) with a data store. You need to provide only simple "model" definitions of resources; ZRM uses the model definitions to create the data store and then supports full create/read/update/delete (CRUD) semantics. In addition, ZRM supports a variety of content formats, including JSON and the Atom Publishing Protocol.

ZRM uses a simple REST model to enable you to focus on the application rather than the persistence details. ZRM does not introduce general purpose object relational mapping (ORM). For example, the ZRM data model is geared toward REST, rather than an arbitrary POJO model, by asserting fundamental persistence assumptions.


Declaring schema as JSON

Schema declaration in ZRM is called resource model declaration and is made in a resource model file using JSON. By default, this file is named /app/models/<model-name>.json and looks similar to Listing 1.

Listing 1
	// Resource Model declaration
	// File: /app/models/citizen.json
	{
	 	"fields" : {
	            		"name": {"type": "string", "max_length":40},
	           		 	"birth-date": {"type": "date"},
	            		"province": {"type": "string", "format":"region"},
	            		"phone-number": {"type": "string", "format":"phone"}
	}}

Analogous to a schema declaration in a ubiquitous relational database management system (RDBMS), a resource model declaration contains the definitions for fields, constraints, and filtered collections among other optional configuration.

If you need to populate the database with initial data, you can declare data in a JSON file. The file should be present in the folder app/models/fixtures. An example is shown in Listing 2.

Listing 2
[
   	 {
       		 "type": "persons",
       		 "fields": {
           		 "id": 301
           		 "first_name": "Bill",
            		"age": 34,
            		"is_child": false
       	 	}
    	},
   	 {
        		"type": "addresses",
       		 "fields": {
            		"id": 38
            		"street": "100 Maple Ave",
            		"city": "Anytown",
            		"state": "NY"
       		 }
    	},
   	 {
        		"type": "persons",
       		 "fields": {
           		 "first_name": "Frank",
            		"age": 28,
           		 "is_child": true
       		 }
    	}
	]

ZRM is contained in the module zero.resource. This module needs to be specified in the /config/ivy.xml file as follows:

<dependency name="zero.resource" org="zero" rev="[1.0.0.0, 2.0.0.0["/>

Or, if using PHP:

<dependency name="zero.resource.php" org="zero" rev="[1.0.0.0, 2.0.0.0["/>

Merely declaring schema or populating entries in the initial-data.json file does not load data into the database. Synchronizing the database is essential. ZRM works with simple one line commands. The command to sync data (that is, to create and populate the database) is:

zero model sync

Once synchronized, data is persistent. For testing purposes, you might need to reset the database. This can be achieved with command:

zero model reset

See Resources for similar commands for database access and configuration.


Configuring and connecting to an external database

Apart from using the default embedded database in the manner above, ZRM can also connect to other databases with the same model and data access. Supported databases include:

  • IBM DB2® V9.5 (System z®, Linux®, UNIX®, Windows®)
  • Derby V10.3.2.1 (network and embedded)
  • MySQL 5
  • Oracle 10g

All database configuration needs to be specified in the familiar zero.config file. The my-database key can be used (Listing 3).

Listing 3
/config/db/my-database = {
    			"class" : "com.mysql.jdbc.jdbc2.optional.MysqlDataSource",
    			"serverName" : "myserver",
    			"portNumber" : 3306,
    			"databaseName" : "MY1STDB",
    			"user" : "root",
    			"password" : "mypassword"
		}

		/config/resource/dbKey = "my-database"

As with embedded databases, the zero.resource module needs to be included through the ivy.xml file:

<dependency name="zero.resource" org="zero" rev="[1.0.0.0, 2.0.0.0["/>

Or, if using PHP:

<dependency name="zero.resource.php" org="zero" rev="[1.0.0.0, 2.0.0.0["/>


Model API

The model API accesses resources programmatically using collection-like constructs. In addition to the basic CRUD programming model, ZRM introduces a list function, called the LCRUD model. The list function enables listing and filtering collection members using simple conditions. The model API can be used in the resource handlers (groovy or PHP) using the methods onList(), onCreate(), onRetrieve(), onUpdate() and onDelete() for the LCRUD operations, respectively. You can define these methods or invoke the default implementation using:

ZRM.delegate()

This code can go into any of the resource handler methods or it can be the only code in the resource handler file. In the latter case, all resource handler methods will take the default implementation. Unlike with SQL queries, the model API avoids nesting and complex loops, and is simple to understand and use.

Sample code for database access

In the several code sections that follow, take care to see that double underscore “__” is used.

Consider the following resource model (schema) declaration in /app/models/persons.json, shown in Listing 4.

Listing 4
	{
    		"fields" : {
        		"firstname": {"type": "string", "max_length": 30},
        		"birthdate": {"type": "date"},
        		"ischild": {"type": "boolean"}
    		},

    		"collections" : {
        		"children": {"memberFilters": {"ischild": true}}
   		 }
	}

To use model API, code should go into resource handler /app/resources/persons.groovy file. The collection is created with this code:

import zero.resource.TypeCollection
Type persons = TypeCollection.retrieve('persons');

Sample code for query processing

Querying the database follows predefined semantics (Listing 5).

Listing 5
	// retrieve the default collection for model 'persons'
	def collection = TypeCollection.retrieve('persons')

	// retrieve member from collection
	def id = joe.id
	joe = collection.retrieve(id)

	// list all collection results
	def all_people = collection.list()

	// using list() with conditions
	def some_people = collection.list(firstname: 'Joseph')
	people = collection.list(firstname__contains: 'se')
	people = collection.list(firstname__endswith: 'ph')

	// paged results from 11th to 20th items in the overall collection
	def paged_people = collection[10..19].list()

	// paged and filtered results
	def filtered_paged = collection.filter(firstname__endswith: 'ph')[201..300].list()

	// excluding results
	def excluded = collection.exclude(ischild: true).list()

	// get a map of members
	def map = collection.in([1, 3, 5])

Sample code for LCRUD

The basic list, create, retrieve, update, and delete operations can be performed using code like that shown in Listing 6.

Listing 6
#List all members
	List<Member> everybody = persons.list()
	everybody.each { person ->
    		println person.firstname
	}

	#List subset of members
	List<Member> somePersons = persons.list(firstname__startswith: 'Jo')
	somePersons.each { person ->
    		println person.birthdate
	}

	#Create a member
	Member person = persons.create(firstname:'Joe', birthdate:'1978-01-21', 
	ischild: true)

	#Retrieve a member
	Member person = persons.retrieve(1)

	#Update a member
	Member result = persons.update(id: '1', firstname:'Bob', birth_date:'1961-12-05')

	#Delete a member
	boolean result = persons.delete(1)

In addition, the model API contains various other methods for filtering, excluding, paging, and so on. See Resources for detailed descriptions.


REST-based access to resource model

As mentioned earlier, WebSphere sMash uses a REST model through resource handlers that defines one method for each of the LCRUD calls. In addition to the model API, there is an HTTP REST API for web-based database access through a URI.

For web-based access to the database, a collection can be read through this URI: http://<server-name>:<server-port^gt;/resources/persons; for example:

http://localhost:8080/resources/persons

The semantics of model API can be followed for the HTTP REST API as well (Listing 7).

Listing 7
#Filtered collection where member instances' firstname field contains 'Jo'

http://localhost:8080/resources/persons?firstname__contains=Jo
		
#Filtered collection where member instances' firstname field contains
'Jo' and birthdate falls on the 25th of the any month.
http://localhsot:8080/resources/persons?firstname__contains=Jo&birthdate__day=25

LCRUD can be performed through HTTP methods (Listing 8).

Listing 8
#Create a member
		POST /resources/persons
		Content-Type: application/json
		{
   			"firstname": "Bill",
   			"birthdate": "1976-09-25"
		}
		#Retrieve a member
		GET resources/persons/1
		#Update a member
		PUT /resources/persons/1
		Content-Type: application/json
		{
   			"firstname": "Janie",
   			"birthdate": "1973-12-04"
		}
		#Delete a member
		DELETE /resources/persons/1

Conclusion

Zero Resource Model is a simple and efficient model for database access in WebSphere sMash. Its rich model API substitutes for SQL queries whereas the REST model provides uniform web access. ZRM provides a ready-to-use, agile method of database management for situational applications that relieves you of much of the database-handling responsibilities through its built-in data handling mechanism.

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere, Web development, Agile transformation
ArticleID=801027
ArticleTitle=Using the Zero Resource Model for database management in WebSphere sMash
publish-date=03142012