Creating a Service Description for a Service that Returns JSON

The HTTPServiceTransport can process a JSON response from a web-based service.  This article demonstrates how to build a service description for a service that returns a JSON response.  I am using the Google GeoCode API WebService.

Attached to this article are two artifacts:

JSONService-GoogleGeoCode.nitro_s

GoogleGeoCodeLookup_json.xml

1. The Service Description XML file

2. A Sample application that uses the service

I will speak mostly to the construction of the service description as that is what is different from other service descriptions that you may have seen/built.  There is nothing different about the input definition and service mapping, therefore I will skip it and move to the output section of the service description.


The first thing that I will point out is that I have provided three different kinds of output based on what the Google API returns:

1. Individual output parameters that will automatically select the first item returned

2. A list of the search results that contains fields for all of the return parameters

3. A list that returns the address components in the raw format of the service

I chose to do this to show the variety of output formats and the flexibility that you have in manipulating the response data to suit your needs.


In general the way that you create your service mappings is not that different from an XML return format.  You have to set the sourceType="json".


Let's look at the code that pulls all the responses into a single table:

<mapping source="transport:response-entity" sourceRef="results" sourceType="json" target="parameter:results">
          <mapping sourceRef="status" sourceType="json" target="parameter:status"/>
            <mapping sourceRef="formatted_address" sourceType="json" target="parameter:list-formatted-address"/>
            <mapping sourceRef="address_components[types='street_number']/long_name" sourceType="json" target="parameter:list-street-number"/>
            <mapping sourceRef="address_components[types='route']/long_name" sourceType="json" target="parameter:list-street-name"/>
            <mapping sourceRef="address_components[types='locality']/long_name" sourceType="json" target="parameter:list-city"/>
            <mapping sourceRef="address_components[types='administrative_area_level_1']/long_name" sourceType="json" target="parameter:list-state"/>
            <mapping sourceRef="address_components[types='country']/long_name" sourceType="json" target="parameter:list-country"/>
            <mapping sourceRef="address_components[types='postal_code']/long_name" sourceType="json" target="parameter:list-postal-code"/>
            <mapping sourceRef="geometry/location/lat" sourceType="json" target="parameter:list-latitude"/>
            <mapping sourceRef="geometry/location/lng" sourceType="json" target="parameter:list-longitude"/>
            <mapping sourceRef="concat('(', geometry/location/lat, ',', geometry/location/lng, ')')"  sourceType="json" target="parameter:list-latitude-longitude"/>
        </mapping>


Note a few things:

1. The outer mapping references the root results element

2. All the rows will be represented by the child mappings.  The child mappings use relative references to specify where the source comes from (sourceRef).  This means that the "results" list object will contain all the rows that are returned from the service call.  Each row will have the parameters that are defined by all the inner/child mappings.

3. I use XPath to parse the JSON results and place each data item into its own named parameter,  for example: address_components[types='route']/long_nameequals list-street-name

4. I have created my own output parameter that is the concatenation of the latitude and longitude.

To test this sample:

1. Copy the xml file into your /opt/ibm/Forms/ServiceCatalog/1 directory.  If the directory already existed then you do not need to restart Leap, the file will get picked up automatically.  You will know that it is ready to use when you see the following in the SystemOut or trace.log:

[8/21/14 15:58:50:203 PDT] 00000017 ServiceFileCa I com.ibm.form.nitro.service.services.impl.ServiceFileCatalogDirectory update Updating service description from C:\IBM\Forms\ServiceCatalog\1\GoogleGeoCodeLookup_json.xml.
[8/21/14 15:58:50:217 PDT] 00000017 ServiceFileCa 1 com.ibm.form.nitro.service.services.impl.ServiceFileCatalog refresh Finished refreshing service descriptions in C:\IBM\Forms\ServiceCatalog\1.

2. Import the sample application (nitro_s file) into your environment.  There is no data to import with this application.

Note: Your server must have internet access to test this sample as it accesses a public Google Web Service.