Introducing IBM WebSphere sMash, Part 1: Build RESTful services for your Web application

Create, assemble, and deploy modern applications with a powerful, yet simple, platform

In this series, learn all about IBM® WebSphere® sMash, a simple environment for creating, assembling, and executing applications based on current Web technologies. In this first article, get a hands-on tour of the innovations that let you create, assemble, and deploy powerful Web applications. Learn how WebSphere sMash is community driven, and about its conventions for creating RESTful Web services. Using a step-by-step example, you set up the environment, create a project, build a RESTful service to expose data, test your application, and import a sample application to consume the RESTful services.

Share:

Roland Barcia (barcia@us.ibm.com), Senior Technical Staff Member, Systems Documentation, Inc. (SDI)

Roland Barcia photoRoland Barcia is a senior technical staff member and lead Web 2.0 architect for IBM Software Services for WebSphere. He is a co-author of IBM WebSphere: Deployment and Advanced Configuration and Persistence in the Enterprise.



Steve Ims (steveims@us.ibm.com), Senior Technical Staff Member, Systems Documentation, Inc. (SDI)

Steve Ims photoSteve Ims is a senior technical staff member and lead of the App Builder for WebSphere sMash. You'll find Steve on the Project Zero forums.



02 September 2008

Also available in Chinese Russian Japanese Vietnamese

Editor's note: When this article was first published, it was based on code in an incubator project called Project Zero. At that point, the name Project Zero referred to the code and the community. The code is now available as a product called IBM WebSphere sMash. Project Zero is now the development community for WebSphere sMash and will continue to offer developers a cost-free platform for developing applications with the latest builds, the latest features, and the support of the community.

Introduction

IBM WebSphere sMash is focused on agile development of Web 2.0 applications following Service-Oriented Architecture (SOA). Web 2.0 applied to SOA allows Web artifacts to extend the reach of SOA. Think of this as RESTful SOA. (Representational State Transfer (REST) is an architectural style.)

RESTful SOA is a subset of SOA that focuses on Hypertext Transfer Protocol (HTTP) and basic RESTful principles. RESTful SOA advocates the use of design patterns that have made the Web a success; it makes sense, and is to our collective benefit, to follow this pattern with application design. Benefits include:

  • Scalability, through caching and stateless interactions.
  • Simplicity, with prerequisites that are typically HTTP and XML or JavaScript Object Notation (JSON) parsing and rendering.
  • A wide-reaching "network effect" from common standards. For example, sites can consume or aggregate Atom or RSS feeds without having to know details about the content.

WebSphere sMash introduces a simple environment for creating, assembling, and executing applications based on popular Web technologies. The WebSphere sMash environment includes a scripting run time for Groovy and PHP, with application programming interfaces optimized for producing REST-style services, integration mashups, and Web interfaces.

WebSphere sMash’s goals are both technical and social. The technical goals are to provide a scalable platform that simplifies application development in three important dimensions:

Create
Simplify development with support for scripting languages (currently Groovy and PHP), conventions that promote RESTful patterns, and catalogs of reusable assets.
Assemble
Enable rapid access and aggregation of disparate services into unified applications, including data flows, orchestrations, and custom mediations.
Deploy
Provide an application-centric run time environment based upon the well known and stable Java™ Virtual Machine (JVM), which is optimized for agile development (small footprint, fast restart).

The social goals relate to the development process itself. WebSphere sMash is being developed in the open, as community-driven commercial development (CD/CD). Project Zero is the development community for WebSphere sMash. The user community can observe and influence technical decisions for WebSphere sMash. Users also have direct access to the development team and the source code itself. This level of transparency for commercial software development is somewhat new for IBM; it leads to a highly effective offering.

In keeping with CD/CD, all the information about WebSphere sMash is available at projectzero.org. This series of articles won't reveal new information about WebSphere sMash, but will give a structured introduction to the underlying concepts.


RESTful services

REST describes a design pattern for implementing networked systems. REST is neither a technology nor a standard; it's an architectural style for exposing resources over the Web. The RESTful architecture adheres to several principles:

  • Requests are client-server, and by nature, use a pull-based interaction style. Consuming components pull representations of state from the server.
  • Requests are stateless. Each request from client to server must contain all the information needed to understand the request and cannot take advantage of any stored context on the server.
  • REST does not necessarily mean there is no state on the middle tier; the state to fulfill the request for a resource is not dependent on that state.
  • Clients and server adhere to a uniform interface. All resources are accessed with a generic interface in the Web-extended SOA world—HTTP along with the HTTP methods: GET, POST, PUT, DELETE.
  • Clients interact with named resources. The system comprises resources that are named using a URL, such as an HTTP URL.

Representational State Transfer (REST) is a style of software architecture for distributed hypermedia systems, such as the World Wide Web.

REST is the key technology for representing services on the Web. It is important to understand that REST works best when exposing data-based services. These data services can then be mixed and matched to build new applications (often called mashups). The following example shows how a client sees a RESTful service.

With http://<host>/customer:

  • GET: Returns list of customers
  • POST: Creates Customer record

With http://<host>/customer/roland:

  • GET: Returns Roland customer record
  • PUT: Updates Roland record
  • DELETE: Deletes Roland record

In this example, the resource being exposed is Customer. The Customer is represented by the URI /customer. Specific customers are represented by appending an identifier to Customer, such as /customer/ims. The HTTP header methods define the intent of accessing the resource.


Application-centric versus server-centric design

In the enterprise, platforms (such as Java EE-based servers) follow a server-centric mind set. Web applications are built and deployed onto an application server platform. Server platforms, such as WebSphere, can provide all the qualities of service that the Java EE specification demands. Examples of such services include queue-based messaging, distributed transactions, or protocol management. Often, the application server runs several applications on the same JVM. Architects design applications around the notion of sharing software and data resources with other applications, with services provided by the application server (even if they were not being used, in some cases).

Even if applications are deployed in isolated application servers, the servers themselves often still carried all the available services. Application servers allow for an enterprise-level integration. Characteristics of enterprise integration include distributed transactions across various systems, queue-based messaging for critical data delivery, or various other types of services. Platforms in the enterprise are designed around managing various protocols and middleware. Sometimes they talk to enterprise databases that service many applications.

The Web 2.0 world involves a class of less-critical integration at the HTTP level. Applications usually are designed around a set of data, meant to be exposed and mixed with other data sets, to create new applications that perhaps the data provider does not anticipate. WebSphere sMash is designed around the notion of being application-centric. You build the application and run it. You do not package an application and deploy it to a multi-application server, like a WAR file inside another JEE container. Each application runs in its own process—JVM.

Part 2 of this series will discuss the design in more detail.

The WebSphere sMash run time is designed to be short lived and to support patterns such as recycling after every request or an idle timeout. WebSphere sMash is a full stack run time. Everything needed to run the application is built into the process, including the HTTP stack. No external proxy or Web server is required, though an external proxy is used for clustering and multiapplication routing.


WebSphere sMash core programming concepts

WebSphere sMash is the foundation of a new, specialized platform that aligns Web 2.0 and SOA to support the next generation of Web-based business applications. This section covers some core concepts. The Developer's Guide provides more details about the concepts.

Scripting and Java as the system language

Scripting languages are a major trend in simplified development. WebSphere sMash aims to help reduce the overhead of developing services by providing simplified APIs around scripting. The default scripting language is Groovy, which is based on Java and enables Java programmers to easily transition to Groovy. Through an extension module, WebSphere sMash also supports PHP as a scripting language.

Events

WebSphere sMash is an event-based system. All the key behavior of the system is exposed to the application as a set of events, with the appropriate event state. As an application developer, your main job is to provide a set of handlers that hook into the well-known system events to achieve desired application behavior. Standard events are meaningful activities that are of interest to applications.

For example, an HTTP request through the system causes a set of events to occur. You can write handlers for these events. Figure 1 shows this concept, with opportunities to hook in events to handle security aspects, or a particular HTTP method (such as GET or POST) event. For more on event handling, see the event processing section of the Developer’s Guide.

Figure 1. Events
Events

You can write an event handler in various ways, as shown in the example in Figure 2. If you use a scripting language such as Groovy or PHP, you don't necessarily need to provide handler registration because WebSphere sMash provides various conventions that reduce or eliminate configuration. You can place scripts in certain directories, and WebSphere sMash will automatically register them as handlers.

For example, the scripts in Figure 2 are placed in a directory called public, which serves as a Web serving root. If the script file is called hello.groovy, then a user can invoke an HTTP GET on http://<host>/hello.groovy. The GET event is emitted, and the handler onGET is invoked. Notice that the first script in the figure is not placed in an event handler method. Because it is in the public directory, WebSphere sMash will invoke the script in response to any HTTP method. Conventions are covered later in this article.

Figure 2. Event handler examples
Event handler examples

Global context

Event handlers in WebSphere sMash do not have explicit input and output parameters, such as request and response Because event handlers in WebSphere sMash are stateless and cannot maintain a variable state across invocations, WebSphere sMash provides the global context as a means to access and maintain all states. The global context provides all of the interesting data about the current event to the application and the mechanism to store information and share information between components of the application.

The global context is scoped and divided into a set of zones. Each zone maintains data with different visibility, and with a different life cycle, as shown in Figure 3. For example, the user zone contains the session state for a given client, is visible only for that client, and maintains the data until the user becomes inactive.

The request zone contains the state of the currently active request, is visible only to components executed for that request, and the state is only maintained until the end of that request.

Figure 3. Global context
Global context

In WebSphere sMash there are seven zones. Some zones are nonpersistent, as described in Table 1. They are in memory only and do not survive restarts.

Table 1. Nonpersistent zones
ZoneDescription
ConfigData in the /config zone is loaded from configuration files. Data is globally visible and is available for the lifetime of the application. Config zone may be modified, but the changes will be lost on JVM restart when the contents are reinitialized from configuration files.
Request Data in the /request zone is visible to the thread that is processing the HTTP request. Request zone is available from the time a request enters the system until the response is sent out.

You may be familiar with servlet programming, whereby the request zone provides a union of functions offered by HttpServletRequest and HttpServletResponse. It includes access to incoming data: request parameters, headers, cookies, POST body, and input stream and outgoing data: outgoing headers, outgoing cookies, and output steam.

Event Data in the /event zone is visible to the thread that is processing the event for the duration of that event. WebSphere sMash provides an event-processing framework that enables loosely coupled components to publish and subscribe to these events.

If an event is delivered to multiple event handlers, all the event handlers have access to the original event data from the event zone.

TmpData in the /tmp zone is visible globally to all threads of an application. It provides a scratch pad area that the application may use to store any objects.

With persistent zones, as described in Table 2, the data survives JVM restarts.

Table 2. Persistent zones
ZoneDescription
UserData in the /user zone is visible to all threads of an HTTP session. HTTP session is identified by the value of the zsessionid cookie found on the request. User zone is preserved across server recycles. The contents of this zone are serialized using Java serialization; only serializable objects should be placed in it.

An HTTP session times out after a period of inactivity. The idle timeout is configured by setting /config/userZoneIdleTimeout in zero.config. Session also times out and is invalidated after the zsessionid cookie expires.

AppData in the /app zone is visible globally to all threads of an application. It provides a scratch pad area that the application may use to store serializable objects. This zone persists across server recycles.
Storage Data in the /storage zone is visible globally to all threads of an application. It provides a scratch pad area that the application may use to store data objects serialized as JSON types, which include List, Map, String, Double, Long, Boolean, and null. This zone persists across server recycles and restarts.

Global context is available from all parts of an application. The method of access depends on the language being used. Java API to the GlobalContext defines the access characteristics. Bindings are provided to this API through Groovy and PHP. For example, the request variable is bound to the request zone, which means you can use a dot notation such as request.myData to access myData in the request zone. The global context looks like a map with access through key-value pairs. You can get, put, list, and delete different keys from the global context. Figure 4 shows some examples of how event handler can access the GlobalContext.

Figure 4. Accessing the global context
Accessing the global context

The global context supports value pathing, which is direct access into certain object types. For example, you can access a list element with zget("/request/myList#3"), or the value of key within a map using zget("/request/myMap#key").


Conventions and the application directory structure

The WebSphere sMash environment provides several conventions that can greatly simplify the development of WebSphere sMash applications, and minimize the configuration information that must be specified. One of the goals of WebSphere sMash is to have as little configuration information as possible. Some of the conventions are common and expected. For example, you can place a script of your application in the public folder, and run that script in response to an HTTP resource with no configuration data. Figure 5 shows an example of a script called hello.groovy with an event handler method for a GET event. This script will be executed when a GET is invoked for http://<application_host>/hello.groovy

Figure 5. Public directory
Public directory

Other conventions are more tailored to a particular pattern. Figure 6 shows an example of storing the Groovy script called incentive.groovy under a particular folder. This approach automatically registers the methods in this folder to respond to HTTP REST events. In this article, you'll learn how this RESTful pattern is used to quickly develop RESTful services to expose your data.

Figure 6. Virtualized directory for RESTful resources
Virtualized directory for RESTful resources

As you walk through building the example, the various virtualized and application directories are explained. For more information, see the "Virtualized directories" section of the Developer's Guide.


Example scenario

You’re almost ready to build your first RESTful service using WebSphere sMash. First, though, this section provides an overview of the scenarios that will be used in this series of articles.

Requirements

Throughout this series you'll build on a common example to learn different concepts. The theme of the scenario involves energy. Consumers want to save money on energy. Energy providers offer rebate incentives based on certain energy patterns. Energy consumers can be home owners, companies, or another entity. For example, a global company might want to build a quick situational application that lets them find energy incentives for which they qualify. They want to build a Web application to allow Internet searches to find applicable energy incentives for their data centers around the world.

For consumers to find incentives, energy providers must be able to provide the incentive data over the Internet. This is where RESTful SOA becomes key. Being able to unleash your content in a RESTful manner allows others to create new applications to make use of this data. Figure 7 shows the use case diagram for the system.

Figure 7. Use cases for the example
Use cases for the example

In this article, you play the role of an energy provider called NJEnergy. You will use WebSphere sMash to expose and manage incentive data.

Data model

NJEnergy has a single database table with their incentive data, as shown in Figure 8.

Figure 8. Incentive table
Incentive table

The goal is to build a WebSphere sMash application to expose the data.

Design RESTful services

Now that the data set is outlined, begin by mapping your data onto a RESTful namespace. It's usually very helpful to create a table for a particular entity to map the resource. Table 3 shows an example of a RESTful mapping to the example resource. You will build this RESTful service.

Table 3. Incentive REST endpoints
ResourceURI Method RepresentationDescription
Incentive list /incentive GET Both a JSON array of objects and an Atom feed Retrieve a list of incentives
Incentive /incentive POST JSON object Create a new incentive
Incentive /incentive/<incentiveId> GET JSON object Retrieve an individual incentive
Incentive /incentive/<incentiveId> PUT JSON object Update a single incentive
Incentive /incentive/<incentiveId> DELETE Delete a single incentive

JSON is the chosen format to represent the data because we'll be using a rich Internet application (RIA) as a front end to the system. For the list of incentives, you will also provide an Atom feed. Most Ajax-based toolkits understand JSON very well, since JavaScript is the main programming language for Ajax in the browser. (For more details about JSON, see Resources.)

Security for RESTful services

After you define the services, you can begin to attach qualities of service to them. Nonfunctional requirements come in different shapes and sizes. ("Why do non-functional requirements matter?" provides a good, practical treatment on nonfunctional requirements.) With REST we are providing HTTP-based services, so applying nonfunctional requirements may be simplified.

The example will deal with security, which means you'll apply security rules to the REST resources by securing URLs. Table 4 shows an example of a REST table with a security focus.

Table 4. Security
ResourceURI Method RoleInstance level security
Incentive /incentive POST admin Yes: A provider can manage only his own incentives.
Incentive /incentive GET All No
Incentive /incentive/<incentiveId> GET All No
Incentive /incentive/<incentiveId> PUT admin Yes: A provider can manage only his own incentives.
Incentive /incentive/<incentiveId> DELETE admin Yes: A provider can manage only his own incentives.
Incentive /incentive?location=<input> GET All No
Any other resource /<Anything Else> ALL No one

Prerequisites

To run the examples in this article, you will need:


Build your first RESTful service using WebSphere sMash

In this section, you launch the application builder, examine some artifacts, add some dependencies, and create a configuration entry for your database.

Launching the application builder and creating an application

The previous version of this article used the Eclipse plug-in for Project Zero. In this version, you will use the Web-based application builder (AppBuilder) for WebSphere sMash.

  1. To launch the AppBuilder, go to a command prompt and issue a command.
    1. You can launch the AppBuilder by going to a terminal window (such as iTerm for MAC or a CMD prompt for Windows). Go to the directory where you extracted zero and run the command appbuilder open (or ./appbuilder open). Figure 9 shows an example using iTerm for MAC.

      If this is the first time running the AppBuilder, the WebSphere sMash run time will begin to download the necessary components to run the AppBuilder from projectzero.org. This happens only the first time you run the AppBuilder.

      Figure 9. Terminal window
      Terminal window
    2. After the command finishes, Firefox should open on its own to http://localhost:8070. This is the location of the AppBuilder. The AppBuilder itself is a WebSphere sMash application. Figure 10 shows the AppBuilder launched within Firefox.
      Figure 10. AppBuilder
      AppBuilder
  2. Now that you've launched the AppBuilder, you can create a new application.
    1. Select New Application as shown in Figure 11. Name the application NJEnergy. Keep the default root directory, and ensure that the module group is stable. You can optionally enter a description. Select Create.
      Figure 11. Create a new application called NJEnergy
      Create a new application called NJEnergy
    2. You should see NJEnergy listed. Click NJEnergy as shown below.
      Figure 12. NJEnergy application
      NJEnergy application

Application artifacts

Before building the application, let's look at some of the application artifacts. You'll use the AppBuilder explorer view, which lets you examine the application directories and files.

Figure 13 shows the application layout and explains the folders. There are several directories. The app folder contains several subfolders where a developer stores scripts. Depending on the subdirectory, WebSphere sMash will apply several conventions. For example, the /app/resources directory is used to create a RESTful service out of a script. You will do so in this article. The config directory contains several configuration files.

Figure 13. Application layout
Application layout

Dependencies

First, add some dependencies to your application. WebSphere sMash uses a technology from Apache Ivy. The ivy.xml file stored in the config directory is where your dependencies are maintained. You could hand edit the file yourself, but this example uses the dependencies page of the AppBuilder.

WebSphere sMash, through Ivy, uses the notion of repositories. There is a local one and remote one. WebSphere sMash applications will declare a set of dependencies. The run time, through the Ivy technology, will look in the local repository to see if the dependency is present. If not, it will download it from a remote repository. By default, the remote repository is located in projectzero.org. However, you can configure different remote repositories. For example, when you ran the AppBuilder for the first time, the sMash run time downloaded the dependencies needed. Ivy also supports downloading based on version. For example, by specifying 1.0.0.0, 2.0.0.0 you are telling WebSphere sMash to obtain the latest version between 1.0.0.0 and 2.0.0.0 (not inclusive).

The AppBuilder provides tools for adding dependencies from your local or remote repository.

  1. Select Dependencies, and you see a box that lists the dependencies of your application. This is read directly from your ivy.xml. Select Add.
    Figure 14. Dependencies
    Dependencies
  2. Begin typing zero.data. Be sure to select Latest major version for Filter By, and select the zero.data package.
    Figure 15. Add dependency
    Add dependency
  3. Add two more dependencies the same way:
    1. zero.atom (sMash libraries for creating Atom feeds)
    2. derby (Drivers for connecting to embedded version of the Apache Derby database)

    Your dependencies should look similar to Figure 16.

    Figure 16. Add more dependencies
    Add more dependencies
  4. Switch back to the explorer tab. Under the config directory, open the file called ivy.xml. You should see all the dependencies listed under the <dependencies> section of the XML file.
    Figure 17. ivy.xml
    ivy.xml

Configuration

The goal of WebSphere sMash is to reduce the amount of configuration needed to create an application by relying on conventions. However, things such as configuring a database and security rules are sometimes required. In this section, you create a configuration entry for your database.

Configuration in WebSphere sMash is done in a zero.config file. As you learned earlier, all data is stored in the global context, which is made up of several zones. You create configuration data within the config zone of the global context. In this section, you create a configuration stanza for the database. The zero.config file contains the configuration for a WebSphere sMash application.

  1. Select the File Editor tab. Under All Files, look for and select the file zero.config.
    Figure 18. zero.config
    zero.config
  2. Add the configuration text to the zero.config file, as shown below. (You can paste it from <download_root>/sMashArticleSeries/Part1/dbconfig.txt in the download file.)
    Figure 19. Database configuration
    Database configuration

Now you need to create the database tables and some sample data. One goal of WebSphere sMash is to let you create applications quickly. One of the ways this is accomplished is by using the zero command line interface (CLI). You can do full sMash development using the command line tool. You can run applications, manage them, manage Ivy repositories, and more. The WebSphere sMash AppBuilder has a console view where you can enter commands. Commands take the form of zero <task> <options>.

WebSphere sMash provides tasks for running database scripts. You will use the zero command line to run a database script.

  1. Within the File Editor, under Recent Files select New File -> Other.
    Figure 20. New file
    New file
  2. Name the file /sql/dbscript.sql, as shown.
    Figure 21. dbscript.sql
    dbscript.sql
  3. Add the SQL text, as shown in Figure 22. (You can paste it from <download_root>/sMashArticle/Part1/dbscript.txt from the download file.)
    Figure 22. SQL script
    SQL script

The next step is to go to the console view of the AppBuilder and run the zero task for running a database script.

  1. Select the Console tab, then select Command Prompt.
    Figure 23. Command prompt
    Command prompt
  2. Enter the command zero runsql NJDB sql/dbscript.sql. The runsql command takes a database name, which we configured in the zero.config, and the script name.
    Figure 24. runsql command
    runsql command
  3. You should see results similar to the following.
    Figure 25. Command results
    Command results

Create a RESTful resource

At this point you are ready to create your RESTful resource by writing a Groovy script and putting it inside the /app/resources directory. Earlier you learned that WebSphere sMash is event-based, and a developer’s job is to write an event handler. There was an example of using the public directory to place Groovy scripts that could have event handlers such as onGET or onPOST. Recall, also, the notion of specialized virtualized directories that allow some default behavior.

In this section you use the /app/resources directory, which is specialized for creating resources for REST services. Table 5 summarizes the URI pattern and HTTP method, as well as which event gets emitted. The URI pattern is for a collection, such as incentives. The most commonly used patterns are highlighted in bold.

Table 5. sMash REST events
URI pattern HTTP method sMash eventDescription
/resources/collection GETlistList all members
POSTcreateCreate a member
PUT putCollection Update collections
DELETE deleteCollection Delete Collection
/resources/collection/{id} GETretrieveRetrieve one member
PUTupdateReplace Member
DELETEdeleteDelete Member
POST postMember Post a Member

If the collection name in the URI is incentive (http:<host>/resources/incentive), then it will look for handlers in a script called incentive.<script-ext> (incentive.groovy or incentive.php, for example). So, if a GET request comes of /resources/incentive, then the list event is emitted and sMash will look for an onList() handler inside of incentive.groovy or incentive.php. If a GET request comes in at the member level, for example /resources/incentive/3, then it will look for an onRetrieve() handler inside incentive.groovy or incentive.php. At the member level, sMash will automatically put the Id in the GlobalContext, as well as any additional pathInfo after the Id.

sMash also supports nested resources, such as /provider/<providerId>/incentive/<incentiveId>. You can create a special incentive.bnd file, which specifies the nesting relationship. Table 6 gives some examples of resource requests, the handler information, and the event data passed in.

Table 6. Event handing and event data
HTTP method For URI … invokes method in app/resources/incentive.groovy… with event data
GET /resources/incentive onList
POST /resources/incentive onCreate zget(“/request/input”) // POST data
GET /resources/incentive/3 onRetrieve zget("/request/params/incentiveId")==3
DELETE /resources/incentive/3 onDelete zget("/request/params/incentiveId")==3
PUT /resources/incentive/3 onUpdate zget("/request/params/incentiveId")==3

To build an incentive service that responds to the five resource events, you first need to create RESTful resources.

  1. Back in the file editor, select New File -> New Resource in (/app/resources), as shown below.
    Figure 26. New resource
    New resource
  2. Add incentive.groovy after /app/resources.
    Figure 27. incentive.groovy
    incentive.groovy

Next, you need to write an event handler to respond to a list event. This will get executed when a client issues an HTTP GET on /incentive.

Add the code shown in Figure 28 (paste it from <download_root>/sMashArticleSeries/Part1/onList.txt in the download file). Here, you are using the zero.data APIs to access a manager (which you configured in the zero.config), which then uses the zero.data API to execute an SQL statement. The results of the query are rendered as JSON. This is a predefined renderer in sMash. If you wanted a custom renderer, you could store a template inside /app/views and pass the name of the script implementing the template.

Figure 28. onList
onList

You can quickly run the application and test it.

  1. Click Start, in the upper-right corner, as shown in Figure 29.
    Figure 29. Run an application
    Run an application
  2. Wait for the application to start. The AppBuilder is issuing the appropriate zero command to start an application. You should see a starting application… icon.
    Figure 30. Starting an application
    Starting an application
  3. Click the application link next to the stop button.
    Figure 31. Open application
    Open application
  4. A new browser tab or page should display the running application. There should be a default index page displayed, as shown in figure 32. You will use the Firefox Poster plugin to test your RESTful services. Select the P icon to launch Poster.
    Figure 32. Default index page
    Default index page

Firefox Poster is a nice extension to Firefox that lets you test your RESTful services, including doing a POST, PUT, and DELETE. You use this tool to test your RESTful interactions.

  1. In the URL, enter http://localhost:8080/resources/incentive as shown below, and select GET.
    Figure 33. GET with Poster
    GET with Poster
  2. You should get a JSON list of incentives.
    Figure 34. /resources/incentive results
    /resources/incentive results

    Click to see larger image

    Figure 34. /resources/incentive results

    /resources/incentive results

You just created a RESTful resource for getting a LIST of incentives. Next, you will create a handler for the retrieve event. This returns a single incentive based on the URI pattern.

  1. Figure 35 shows the onRetrieve handler. (You can paste it from <download_root>/sMashArticleSeries/Part1/onRetrieve.txt from the download file.) Within the query string you have a GString variable accessing the global context. The ID is stored in the request zone, as shown earlier. (Under the covers, the zero.data API uses a prepared statement.)
    Figure 35. onRetrieve
    onRetrieve
  2. Back in the Firefox Poster tool, you can now test the URI. Enter http://localhost:8080/resources/incentive/1 and select GET.
    Figure 36. Test onRetrieve
    Test onRetrieve
  3. You should get the result shown in Figure 37.
    Figure 37. onRetrieve result
    onRetrieve result

So far, you've just returned JSON data. In Web 2.0 applications you may want to return an Atom feed. You update the onList method to return an Atom feed. You might want to provide a subset of lists.

  1. Replace the onList implementation with the code shown in Figure 38. (You can paste it from <download_root>/sMashArticleSeries/Part1/onListAtom.txt from the download file.) A few things to note:
    • First, look for a query parameter using the GlobalContext. Notice that you can access list elements directly.
    • After issuing the query, the code checks for a request parameter for a format element. If it exists, it sees if it is atom. If so, you use Groovy scripting to generate a structure with the required Atom fields and render it.
    Figure 38. onList that returns Atom or JSON
    onList that returns Atom or JSON
  2. Go to your Firefox browser and, in another tab, enter http://localhost:8080/resources/incentive?format=atom as shown in Figure 39.
    Figure 39. Atom result
    Atom result

So far, you have coded GET methods for reading. Now you can code the POST, PUT, and DELETE methods.

  1. Add the code as shown in Figure 40. You can paste it from <root>/free (<download_root>/sMashArticleSeries/Part1/updates.txt in the download file). You will notice a few things.
    • You have a method handler for create, update, and delete that corresponds to POST, PUT, and DELETE http methods, as shown previously.
    • WebSphere sMash has JSON decode and encode methods. You can easily pass the request.input[] variable from the GlobalContext into the decode method to get a script representation (Groovy Map for a JSON object, or a Groovy List for an array) of the input.
    • The data is passed to the query as a Groovy GString.
    • You set the appropriate HTTP response.
    Figure 40. Update methods
    Update methods
  2. Back in the Firefox Poster tool, enter the URL http://localhost:8080/resources/incentive. In the content area, enter the JSON object, as shown in Figure 41. (You can paste it from (<download_root>/sMashArticleSeries/Part1/postInput.txt from the download file).
    Figure 41. Test POST
    Test POST
  3. You should get back a 204 response that the update is successful. Notice the location header has the URL with the newly posted item.
    Figure 42. POST response
    POST response
  4. Change one of the data items, such as the name. Copy the POST URL (or add the ID to the end) back in the Poster input and issue a PUT.
    Figure 43. PUT request
    PUT request
  5. Sometimes, depending on firewalls, you cannot issue a PUT. By adding the X-Method-Override header and put Value as PUT, as shown in Figure 44, you could also do a PUT through a POST. This is only if the PUT fails. You should get a 204. You can issue a GET on the same URI to ensure the update happens.
    Figure 44. POST override
    POST override
  6. Issue a Delete on the same URI.
    Figure 45. Delete
    Delete
  7. You should get a 204, as shown in Figure 46. If you do a GET, you should get a 404 not found.
    Figure 46. Delete result
    Delete result

Securing RESTful resources

When building a RESTful application, you must take security into account. In this section you secure the POST, PUT, and DELETE methods for incentives to people who are authorized to access the provider application. GET will be unsecured to allow consumers to find incentives over the Internet.

Security rules are entered in a zero configuration file. We will use the default security.config. However, you could store security information in a separate configuration file and include it in zero.config.

  1. Go to the File Editor. Under Recent Files, select the zero.config file.
    Figure 47. zero.config
    zero.config
  2. Enter the security rules, as shown in Figure 48. You can paste them from securityRules.txt (<download_root>/sMashArticleSeries/Part1/securityRules.txt from the download file). A few things to note:
    • There is a default rule configuration that you include to get the needed patterns. Notice that you specify a condition. In this case, we are looking for an HTTP request that matches /resources/incentive (and anything after it denoted by (/*|?) and the HTTP methods DELETE, POST, or PUT). This information is in the GlobalContext, and is called during the secure phase of the request life cycle shown earlier.
    • You specify the authentication type, which is Basic. (WebSphere sMash supports other types such as Form, Single Sign-on, or Open ID. See the Security section of the WebSphere sMash Developer’s Guide). Then you can specify Groups, Users, or Roles allowed to access this URI rule. A special group is specified that matches any authenticated users.
    Figure 48. Security rules
    Security rules
  3. WebSphere sMash provides a default file-based registry that is ideal for development. Later when deploying you can switch to an LDAP-based or custom-based registry. You can create users in the default rile registry by using the zero CLI.

    Go to the console tab and select the command prompt option. Enter the command: zero user create admin passw0rdas in Figure 49.

    Figure 49. Create users
    Create users
  4. The results should display as shown in Figure 50.
    Figure 50. Zero command results
    Zero command results

Since you made a configuration change, you have to restart the application to test.

  1. Click Stop in the upper right corner as shown in Figure 51.
    Figure 51. Stopping the application
    Stopping the application
  2. Click Run to start the application.
    Figure 52. Running an application
    Running an application
  3. Go Back to the POSTER tool and issue a GET to http://localhost:8080/resources/incentive, as shown in Figure 53. A GET request is unsecured, and you should get a list as you did before.
    Figure 53. Unsecured GET
    Unsecured GET
  4. Issue a POST request with the same input as before. You can paste it from postInput.txt again (<download_root>/sMashArticleSeries/Part1/securityRules.txt from the download file).
    Figure 54. POST request
    POST request
  5. You should get a prompt to enter a user and a password. Enter admin/passw0rd.
    Figure 55. Security prompt
    Security prompt
  6. You should get a 204 with a new resource created. You can similarly test PUT and DELETE.
    Figure 56. POST results
    POST results

Conclusion

In this article, which updates a previous article about Project Zero, you used the product code from WebSphere sMash. You were introduced to the product and learned that WebSphere sMash follows an event-based architecture. The global context is a means to maintain all states for an application. WebSphere sMash is application-centric, with several virtualized directories that help you use conventions to reduce the amount of configuration in an application.

You used WebSphere sMash to build a REST-based application that exposed incentive data. You used the new AppBuilder, a Web-based integrated development environment for building sMash applications. Finally, you learned how to secure RESTful resources using sMash security rules.

In the next article you will delve deeper into REST by building the consumer application. You will use another pattern for building REST services called the zero resource model (ZRM). You will also go into building rich Internet clients to RESTful resources using the Dojo Toolkit.


Download

DescriptionNameSize
Samples for this articlesMashArticlePart1.zip10KB

Resources

Learn

Get products and technologies

Discuss

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 developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Architecture, Web development, WebSphere
ArticleID=334981
ArticleTitle=Introducing IBM WebSphere sMash, Part 1: Build RESTful services for your Web application
publish-date=09022008