Skip to main content

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

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

All information submitted is secure.

  • Close [x]

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.

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

All information submitted is secure.

  • Close [x]

developerWorks Community:

  • Close [x]

Build a RESTful service on CICS with PHP

Robin Fernandes (robin_fernandes@uk.ibm.com), Software Developer, IBM
Photo of Robin Fernandes
Robin Fernandes joined IBM's Java Technology Centre in Hursley, United Kingdom as Software Developer after graduating from Imperial College in 2003. His current focus is a Java-based runtime for PHP, which is used in the CA1S SupportPac and WebSphere sMash. He also regularly contributes test cases and patches to php.net and enjoys experimenting with audio software in his spare time.
Jonathan Lawrence (jlawrence@uk.ibm.com), Software Developer, IBM
Photo of Jonathan Lawrence
Jonathan Lawrence joined IBM's Java Technology Centre in Hursley, United Kingdom as a Software Developer in 2006, after 4 years in Hursley's Software Services department where he was a CICS and Cross-platform Integration Specialist. He designed the CICS integration aspects of the CA1S SupportPac.

Summary:  CICS® Transaction Server® (TS) is a powerful transaction manager designed for rapid, high-volume processing. SupportPac CA1S uses technology from IBM WebSphere® sMash to enhance CICS TS with PHP scripting capabilities and Representational state transfer (REST)-related features. This tutorial shows how you can use PHP to quickly and easily work with CICS programs and expose them on the Web. If you are a PHP developer, find out how you can use your skills to interact with enterprise assets in CICS; if you are a CICS developer, see how PHP provides a simple and agile way to manipulate your existing resources.

Date:  21 Apr 2009
Level:  Intermediate PDF:  A4 and Letter (409 KB | 37 pages)Get Adobe® Reader®

Activity:  12723 views
Comments:  

REST basics in CA1S

RESTful event handlers in SupportPac CA1S

Overview

WebSphere sMash introduces a set of conventions that simplify the creation of RESTful Web services (for more information, see the WebSphere sMash documentation in Resources). SupportPac CA1S adopts a subset of these conventions. They are described in detail in the CA1S documentation (see Resources), but to summarise:

  • CA1S can be configured to treat requests to certain paths as RESTful. In a default CA1S installation, this applies to paths under /ca1s/resources
  • When a request on such a path is processed, information about the targeted resource is derived from the URI as follows:
http://<host>/ca1s/resources/<resourceName>[/<resourceID>[/<…more/resource/info…>]]
             

  • A resource handler script corresponding to the resource name is looked up. The PHP engine will execute that script, then attempt to invoke a specific method within the script depending on the HTTP method of the request and whether the URI contains an identifier after the resource name.

Table 5 shows the mapping from the HTTP request type to the method that will be invoked, assuming the resource is named 'book':


Table 5. RESTful events handler methods
Request URI HTTP Method Handler method invoked in ca1s/work/resources/book.php
Collection URI, e.g.
http://<host>/ca1s/resources/book
GET book::onList()
  POST book::onCreate()
  PUT book::onPutCollection()
  DELETE book::onDeleteCollection()
Member URI, e.g.
http://<host>/ca1s/resources/book/10
GET book::onRetrieve()
  POST book::onPostMember()
  PUT book::onUpdate()
  DELETE book::onDelete()

Resource handler scripts do not need to implement all the methods shown in Table 5. If a method is not found for a given event, no error is raised. The most commonly implemented event handlers are for the events that correspond to List, Create, Retrieve, Update, and Delete ("LCRUD") operations on the resource, as highlighted in bold in Table 5.

Example

The example shown in Listing 6 prints a different string for each event:


Listing 6. A skeleton resource handler script


<?php
class book {
	function onList() {
	  echo 'LIST all books!';
	}
	
	function onCreate() {
	  echo 'CREATE a book!';
	}
	
	function onRetrieve() {
	  echo 'RETRIEVE a book!';
	}
	
	function onUpdate() {
	  echo 'UPDATE a book!';
	}
	
	function onDelete() {
	  echo 'DELETE a book!';
	}	
}
?>
               

To try it out, copy the script above to your CICS system in ca1s/work/resources/book.php (note that the name of the class declared in the script must match the script file name). Then, access it with different HTTP methods, with and without an identifier on the URI, using a REST client such as the Poster add-on for Firefox. You will see that the event handlers are triggered as appropriate. For example:


Figure 2. A GET request on the book resource with an identifier triggers the onRetrieve() event handler
A screenshot of the Poster add-on for Firefox depicting the                   onRetrieve() event in action.  The Response reads: RETRIEVE a book!

Figure 3. A POST request on the book resource without an identifier triggers the onCreate() event handler
Another screenshot of the Poster add-on for Firefox, this time                   depicting the oncreate() event in action.  The Response reads: CREATE a book!

Event handlers not being invoked?

Confirm that the following are all identical (they should all represent the resource name):

  • the first path component of the request URI after the 'ca1s/resources/' prefix
  • the file name of the resource handler script up to the .php extension
  • the name of the class defined in the script

Accessing request data with zget()

Scripts may access various attributes of the inbound request by using the zget() function, which is built in to CA1S. Examples include:

  • The body of the inbound request as a string, transcoded from the request encoding to the PHP runtime encoding:
$data = zget('/request/input/transcoded');

  • Query string parameters (as well as POST and PUT parameters, if they are form encoded):
		$value = zget('/request/params/<paramName>');
             

  • The ID of the requested resource, as specified on the inbound URI.
		$id = zget('/request/params/<resourceName>Id');

  • The part of the URI following the resource ID, if available:
		$data = zget('/event/pathInfo');
            

To experiment with zget(), modify the method book::onUpdate() in book.php as follows:

function onUpdate() {
  $id = zget('/request/params/bookId');
  $data = zget('/request/input/transcoded');
  echo "You attempted to update book $id with data $data";
}

Then, access a specific book resource with a PUT request in order to trigger the update event.


Figure 4. Testing zget with Poster
A screenshot of the Poster add-on for Firefox, this time                   depicting zget() in action.  The Actions: PUT and Content to Send:Hello World fields are circled in red.  The Response reads: You attempted to update                   book 40 with data: Hello World!

The zget() function is based on the Global Context feature in WebSphere sMash (see Resources). A description of the full functions provided by zget() in CA1S and its differences compared to the version in WebSphere sMash is available in the CA1S documentation. You may also use PHP's standard mechanisms for accessing request data such as the $_GET superglobal, the php://input stream, and so on.


Using JSON as the service's data interchange format

REST helps define a simple and consistent interface to expose a resource as a service, but it does not impose a format for the service's input and output data—this decision is left to the implementer. JSON is a popular option, because it is simple, human readable, and supported by a wide range of client- and server-side languages.

Encoding PHP variables into JSON data

The following code listing shows how an onRetrieve() handler would send a book resource encoded as a JSON string. Note that in this example, for simplicity, the book details are hard-coded in the handler. In the next section, you'll see how to retrieve that information from the COBOL library program.

function onRetrieve() {
  $id = zget('/request/params/bookId');
  // ... establish that book with ID $id is Heart of Darkness ...
  $book['title'] = 'Heart of Darkness';
  $book['author'] = 'Joseph Conrad';
  echo json_encode($book);
}

The response body returned from a GET request to a member URI like /ca1s/resources/book/10 would contain:

{"author":"Joseph Conrad","title":"Heart of Darkness"}

Decoding JSON data into

Similarly, here's how an onCreate() handler would process input data in the request that is encoded as JSON. Again, for simplicity, we simply dump out the decoded data; in a real world case, we would use the data to create a new resource.

function onCreate() {
  $inputData = zget('/request/input/transcoded');
  $book = json_decode($inputData, true);
  // ... Create new book resource based on data in $book ...
  // Dump out the variable to illustrate:
  var_dump($book); 
}
             

Sending data like

{"author":"Margaret Atwood","title":"Oryx and Crake"}

in the body of a POST request to the collection URI ca1s/resources/book would return:

array(2) {
  ["author"]=>
  string(15) "Margaret Atwood"
  ["title"]=>
  string(14) "Oryx and Crake"
}

4 of 9 | Previous | Next

Comments



static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Web development, Open source
ArticleID=383593
TutorialTitle=Build a RESTful service on CICS with PHP
publish-date=04212009
author1-email=robin_fernandes@uk.ibm.com
author1-email-cc=
author2-email=jlawrence@uk.ibm.com
author2-email-cc=