Wednesday, 22 April 2015

Consuming an HTTP/JSON REST service with webMethods

Type: How-to and step-by-step tutorial
Tags: REST, HTTP, JSON
Product: webMethods Integration Server. Tried it with version 9.6

When to apply: You've got a flow service that needs to consume a REST service - whether it's RESTful or "not so RESTful".
This document explains how to consume a REST call by converting an Integration Server document to JSON and sending it by making an HTTP call.

Example repository: https://github.com/juanaltech/webmethodsRestConsumerExample

Summary of steps

Prerequisistes

Create a document type that defines the structure of the JSON content.

Steps

In the flow service that calls the REST service, add the following:
  1. Populate the content of document of the type created in the initial step
  2. Use the pub.json:documentToJSONString built-in service to convert the document to a JSON string
  3. Use pub.client:http to make an HTTP request. The json string from the previous step needs to be mapped to data/string. You'll also need to set values for fields such as url and method. Finally, add the necessary headers for the request. You'd normally need to add:
    • Content-Type, with a value of the resource type for the request and, optionally, the encoding. This may be application/json; charset=UTF-8 in simple cases.
    • Accept, with a value of the expected resource type of the response. This may be application/json in simple cases.

Step-by-step Example

In this simple example, I'll show you how to consume a hypothetical REST service in order to send information about a car.

You may grab the code from: https://github.com/juanaltech/webmethodsRestConsumerExample

Create package and folder

You may use use an existing package with a folder hierarchy. In our example, we'll create a new package package and a restconsumer folder. First, select New Package, type in the the package name, RestConsumerDemo, and select OK. Next, right click on the containing package and select New Folder and create a new folder called restconsumer.

Create a document type

Right click on the restconsumer folder and select New Document Type. We'll assign it a name of Car

In the document type pane, right click on a blank space and select insert String to create a field named make. Repeat this step to create a field named model.

Create the flow service


Right click on the restconsumer folder and select New Flow Service. Type in consume as the name and hit OK.

Right click on an empty spot in the Tree tab, select Insert, Map. 


Make sure the pipeline view is visible and then drag the Car document type from the Package Navigator into the Pipeline Out section in the pipeline view. This will create a new document of that type. Rename the document's name to car.

In order to assign values to make and model, right click on the field and select "Set Value". We'll use "Volkswagen" and "Golf".

Add pub.json:documentToString service invocation

In order to add a new step in the service, right click on an empty spot in the Tree tab again and select Insert from the context menu and select Invoke. Navigate to the WmPublic package, select the pub/json folder and then select the documentToString service.

Map the car document in pipeline in to the document field in documentToJsonString by dragging one field onto the other - once you do that you'll see a black line connecting both fields. Notice a jsonString value is created automatically in Pipeline Out.


Add pub.client:http invocation

Right click on an empty space in the Tree tab again. This time insert an invocation to pub.client:http from the public WmPublic package.

Now all the action happens in the the pipeline view. Assign all the values that are required. In this example, we'll assign the following:
  • url: specify the URL to your resource. We'll assume the resource is available at http://localhost:8089/cars
  • method: we'll use put in our example
  • Map the jsonString field to the data/string field in pub.client:http
  • Right click on the headersService In field and to add headers with a type of String. We'll add two:
    • Content-Type, which will have a value assigned of application/json; charset=UTF-8
    • Accept, with a value of application/json

Try it

You may now run the consume service by right clicking on it, selecting Run As and Run Flow Service. If you capture the request, you'll notice a string like this is sent in the body: {"make":"Volkswagen","model":"Golf"}

If you get a connection refused error, it's most likely because there's no service provider on the URL you specified. Once you make sure it's pointing to the right location, you should see a value of 200 on the response status code inside the results pane.



Recommendations

In order to provide robustness, a complete implementation should typically check the header's status (HTTP status code) to ensure the returned value falls in the range between 200 and 299. 

When  other values are returned, e.g., 500, your code should typically exit with a failure or throw an  exception.