Working with REST interfaces in Rational Integration Tester

REST (Representational State Transfer) is a simple, stateless architectural style typically running over HTTP which is common among web service implementations.  REST depends on the use of standard methods such as GET, POST, PUT and DELETE. Until recently, there wasn’t an accepted standard for how REST services were defined. There was no service specification that Rational Integration Tester could synchronized to as an external resource. Web Application Description Language (WADL) is a specification recently ratified by the W3C for defining REST services. WADL models the resources provided by a service and the relationships between them.  We will look at WADL in a bit, but it is important to understand how to define Rational Integration Tester REST schemas manually for a few reasons. First of all, you really need to understand what’s happening under the hood to understand how RIT uses the schema later. Secondly, WADL is new enough that many existing REST services do not have WADL specifications. And finally, there are some limitations in Rational Integration Tester’s support for WADL that may mean you need to manually adjust your model after synchronizing.

Creating REST schemas manually

The Login example

Forget about WADL for a moment. Let’s look at what a simple REST implementation might look like as an example. Let’s say the fictitious JKE Bank has a REST system that authenticates users of its online system. The REST URI for authentication looks like this:

http://services.jkebank.net/user/<username>?password=<password>

Yes, I realize passing the password as a query parameter is highly unsecure, but play along with me, please. It illustrates my point well. Julie Brown is an account holder at JKE and she uses her pet cat’s name, Snuggles, as her password. The request to authenticate the user jbrown might look like this:

http://services.jkebank.net/user/jbrown?password=snuggles

If you simply record a request message to this URL with Rational Integration Tester, how should the elements of the URL be interpreted? What constitutes the “operation” of this system? If you want to create tests for different users, you will want to create data-driven tests and stubs. How can you get RIT to substitute values from a test data file for the “jbrown” element of the URL? The answer lies in a REST schema definition in the Schema view of the Architecture School. REST schemas enable you to define which elements of the URL should be parametrized and which ones should be considered fixed values. To make the process of defining the schema easier, RIT provides the ability to import a URL template.

Once again, let’s use the JKE example to illustrate. Let’s say you have defined an HTTP connection in the logical view and associated it to a physical resource representing your web server. You record the request and you see something like this:

Recorded events for login of user jbrown

Recorded events for login of user jbrown

If you select those two events and attempt to save them as unit test with a simple data set, you will see where the problem comes in.

First Attempt at a Data Driven Test

First Attempt at a Data Driven Test

You would want the username to be a column in your data file, but only the password has been identified as a parameter.  So if you go ahead with this test as it is, this test can only be used for this one username – jbrown.  Furthermore, notice that the operation has been identified as jbrown.  In REST terms, jbrown is the unique ID for the resource.  The operation should really be “user” – the element of the URI just before the unique ID.

This illustrates why Rational Integration Tester needs a little coaching in order to properly identify the fixed versus parameterized elements of the URI.  That coaching comes in the form of a REST schema which is created in the Schema Library view of the Architecture School perspective.  The simplest way that I have found to do this is to follow the steps below.

Enhancing the REST schema

Switch to the Schema Library view of the Architecture School perspective and select the REST schema type on the left. Here you see that RIT did create a schema when you attempted to create a test from the recorded events, but it needs some human intelligence applied to really make it useful.

Initial REST Schema for JKE User

Initial REST Schema for JKE User

First of all, the schema name is extracted from the hostname of the physical resource that was recorded.  That’s not entirely useful, so we will change that to “JKE Services”.

Next, let’s edit the template for the URL by selecting it and clicking the edit icon.

Initial template for the JKE User URL

Initial template for the JKE User URL

On the left side, you see the URL path segments.  On the right, you see any query segments.  The password part is pretty easy – it’s a pretty fair bet that anything that appears as a query parameter value is something you will want to parameterize.  That’s why you see the curly braces around the password value.

But since RIT has only seen one URL, it has to make some guesses on what the URL represents.  But the best guess RIT can make is that all elements of the URL are fixed. You can edit the schema a bit to make jbrown a parameter rather than a fixed element. You can also rename that parameter to something more descriptive of what it really represents, which is “username”.

Username parameter

Username parameter

The last thing you probably want to do is to change the template name from jbrown to something more appropriate like “user”.

Saving the test – Redux

With this schema in place, when you save the recorded events as a data-driven test, both the username and password are recognized as parameters and the operation name is identified as user.

Updated Data Driven Test

Updated Data Driven Test

jbrown will be placed into the test data file as a parameter along with the password.

Test Data Preview

Test Data Preview

The retrieve accounts example

Next, let’s look at the REST request that retrieves Julie’s account information:

http://services.jkebank.net/user/jbrown/accounts

If you record the request and its response then attempt to save the events as a data-driven test, you will find again that the username element of the URL will not be identified as a parametrized value.  I will use a slightly different procedure to create this template to demonstrate how you can import a URL template.

Creating the REST template for accounts

Copy the URL of the operation from the Header section of the Events View in Recording studio. In the Schema Library, use the Import URL Template tool and paste your URL into the dialog and click OK.

Initial Accounts Template

Initial Accounts Template

You can see here that RIT has done a rather curious thing.  In the absence of a query parameter, RIT makes the assumption that every element of the URL must be a parameter. That’s not what you wanted either but again, you can edit the schema such that the username is the only parameter.

Updated Accounts Template

Updated Accounts Template

Now what about that WADL…

Now, all that is good to know, but I’m one who likes to avoid extra work if I can. So let’s get back to WADL…

As I mentioned earlier, WADL is relatively new and I have found that, although there is a W3C Specification for WADL, people interpret and apply the spec in various ways.  Let’s take a look at ways we could represent the JKE interfaces in WADL.

Here’s how I think these services would be represented in WADL:

JKE Banking Fully Structured WADL

JKE Banking Fully Structured WADL

I mentioned some limitations in Rational Integration Tester’s WADL support at the beginning of this post.  One of the limitations is that RIT doesn’t support parameters at the resource level yet – that’s something we expect in a future release.  So I’ve reorganized the resource hierarchy a little in the following iteration of the WADL file:

Restructured JKE WADL

Restructured JKE WADL

Now go to the Synchronization view of the Architecture School perspective in RIT and add a WADL reference to the external WADL file.  This can be done with the Web > WADL toolbar action or the Add a new item to the view toolbar action.  When you synchronize, you will see the following elements.

Synchronized WADL

Synchronized WADL

Let’s browse the model artifacts to see what was created by going to the Schema Library.

Schema Library for WADL

Schema Library for WADL

RIT left the schema untitled and uses a default name for the schema template of “url name”.  This is something you should probably change to be more human friendly so name the schema JKE, the first template user and the second accounts.

Updated Schema Library for WADL

Updated Schema Library for WADL

In the Logical View, the endpoint and two operations were created.

Synchronized elements in the Logical View

Synchronized elements in the Logical View

That first operation name looks odd.  This is another limitation of the RIT support today.  If the last element of the resource URL is a parameter, RIT doesn’t really know what to do about a name for the operation.  You can rename the operation to something more appropriate like user.

Now open the user operation properties.

User operation properties

User operation properties

Several attributes such as the operation pattern and method were imported as well as the request schema.

One more limitation – My WADL had specified a mediaType of application/json but the schema for the Reply has been set as Text.  This should be changed by browsing to JSON > Object.

Summary

Rational Integration Tester has some pretty powerful support for REST testing and virtualization.  The nature of the beast of REST typically means you will need to do some coaching in the schema library to get RIT to understand the meaning of your application resources.  RIT 8.5.1 has introduced support for WADL file synchronization.  Although this support is evolving, there is a lot of value in using WADL to jump-start your model creation.

Advertisements

3 thoughts on “Working with REST interfaces in Rational Integration Tester

  1. This is really an excellent article. I followed your article and I am able to parameter the REST services, but I am facing the below issues,

    They are two services,
    1) /api/{accountid}
    2) /api/{accountid}/addresses

    I have created the stubs for above two services and started. The responses are coming perfect and well.

    But when I hit any of the service like

    For service: /api/{accountid}/addresses for example /api/1234/addresses, there is a hit in /api/{accountid} as well in task monitor showing string 1234/addresses is not matching to {accountid} trying next.

    For service: /api/{accountid} for example /api/1234, there is a hit in /api/{accountid}/addresses as well in task monitor showing Path is missing trying next

    Due to this both the services incremented by one every time when I hit the particular service. We are getting confused which service got worked by seeing the numbers in RTCP.

    Thanks,
    Chandrakanth.

    • Chandrakanth,

      The situation you are in is that your stubs are matching not only the URL paths that you want, but also URLs with either more or less specific path segments. There are a few ways to adjust your stubs to do what you want.

      1. Stub input filtering. You could put an input filter on the URL in the request headers in each of your stubs. This will cause the stub to only fire if the Filter is matched. Since your URL will have a parameter (accountid), you won’t be able to use a simple equality test if you plan to use more than one accountid. You can change the Action Type to Regex and filter based on pattern matching.

      2. Operation Resource Name settings. On the Stub tab of the resource’s properties dialog, you can choose to filter the stub’s response based on the Resource Name you provide. You can optionally disallow subpath matching. Unfortunately, the Resource Name field does not yet support parameters so this is not likely to really solve the problem in REST situations like yours because you can’t ignore parameterized segments in the path.

      3. A guard on the stub events. Events in stubs have the concept of a Guard. Guards enable you to write code to determine if your stub should fire. For example, I added a store Tag to the URL in my stub request headers, then wrote Javascript code to filter based on a regular expression that verifies the URL form.

      For my user stub:
      var re = new RegExp(“^/user/[^/]*$”);
      re.test(tags[‘URL’]);

      and for my Accounts stub:
      var re = new RegExp(“^/user/.*/accounts$”);
      re.test(tags[‘URL’]);

      Hope this helps.

      Dennis

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s