Executive Summary
DataPower has first class support for JSON message processing through two frameworks: JSONx and JSONiq. They have their pros and their cons. With JSONx, the message is converted into XML. This encapsulates the input message format from subsequent processing steps and allows the continued use of existing XML tools and experience. With JSONiq, a new syntax is introduced but with the benefit of not requiring an intermediate XML format. This can be useful if your company is already a strong supporter of XQuery, weak on XSLT or just looking for the right tool for the job. In this article, we’ll discuss JSONiq processing in DataPower.
Introduction
JSON is an encoding standard for data interchange that is becoming the standard for services, displacing SOAP/XML. DataPower provides two distinct methods of working with JSON: JSONx and JSONiq, an extension of XQuery. With JSONx, the data is converted into XML. With JSONiq, the data can be queried natively. This series will discuss the history of the XML appliance and show examples of how to work with JSON in the IBM DataPower Gateway environment.
JSONiq
Introduced in Firmware 6, JSONiq allows DataPower to work directly with JSON formatted messages, bypassing any need for an intermediate XML conversion step. It is an extension to XQuery version 1.0 and the version of the specification implemented by the DataPower platform is 0.4.42. It can extract, filter, transform and query JSON messages. It also has the ability to transform JSON messages into XML. In summary, JSONiq can be used to process JSON in the same way that XML can be processed by XSLT.
Sample Input JSON
This is JSON data that will be used in the subsequent JSONiq examples.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "name" : "John Smith", "sku" : "20223", "price" : 23.95, "shipTo" : { "name" : "Jane Smith", "address" : "123 Maple Street", "city" : "Pretendville", "state" : "NY", "zip" : "12345" }, "billTo" : { "name" : "John Smith", "address" : "123 Maple Street", "city" : "Pretendville", "state" : "NY", "zip" : "12345" } } |
JSONiq – Extraction
In this example, we’ll extract the shipTo object from the incoming payload.
1 2 3 4 |
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; declare option jsoniq-version "0.4.42"; declare option output:method "json"; .("shipTo") |
In this example the ‘.’ is used to refer to the root of the input message. ‘.(“shipTo”)’ outputs the root element’s ‘shipTo’ value from the JSON payload.
JSONiq – Message Filtering
In this example, we want to return an error if the “state” in the “shipTo” object is Hawaii. Otherwise we’ll just return the input document untouched.
1 2 3 4 5 6 7 |
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; declare option jsoniq-version "0.4.42"; declare option output:method "json"; if (.("shipTo")("state") = "HI") then fn:error(fn:QName('http://example.org/mine', 'myerr:noshipHI'), 'Sorry, we do not ship to Hawaii.') else . |
From this example, we can walk the JSON hierarchy via the (..)(..) notation and perform standard equality checks. Also note that the input JSON is passed untouched to the output through the ‘else .’ statement when the state is not Hawaii.
JSONiq – Transform to XML
The performs the same transformation as above, but into an XML format instead.
1 2 3 4 5 6 |
declare option jsoniq-version "0.4.42"; <order> <name>{.("name")}</name> <price>{.("price")}</price> <state>{.("shipTo")("state")}</state> </order> |
In this example, note the lack of an opening bracket ‘(‘ after the declare statement. To denote inlined JSONiq processing statements, curly braces ‘{}’ are used.
JSONiq – DataPower Extensions
DataPower extensions can be accessed from JSONiq as well. In this example, the http request headers are returned.
1 2 3 4 5 6 7 8 9 |
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; declare namespace dp = "http://www.datapower.com/extensions"; declare option output:method "json"; declare option jsoniq-version "0.4.42"; [ for $h in dp:variable('var://service/header-manifest')/headers/header return { $h : dp:http-request-header($h) } ] |
The use of a square bracket ‘[]’ denotes an array. Each HTTP header is written as a line of JSON with the header name as the key.
Running JSONiq
In your processing policy, drag in a new transform action and set the following options:
- Use Document Processing Instructions: Transform with a processing control file, if specified
- Input language: JSON
- Transform Language: XQuery
- Transform file: Select your .xq file
Note that if your file does not end with the .xq extension, then it will not appear in the ‘transform file’ drop box list.
Conclusion
Part two talked about JSONiq and it’s value in being able to work with JSON without requiring an intermediate format. JSONiq introduces an entirely new layer of programming constructs which may not be a very good fit for XML-centric enterprises. My recommendation is to stick with JSONx and XSLT-based tooling as you have already made a strong commitment to those technologies, but continue to keep an eye on the evolution of JSON as a business integration technology. You may one day find out that every new service is now JSON based and clinging to XML formats is holding your platform back.
Share this Post