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.
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["/>
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]) |
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 |
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.
-
Documentation: Zero Resource Model overview
-
Troubleshooting the Zero Resource Model
-
Model
API details
-
HTTP
REST API details
-
IBM developerWorks WebSphere




