PI REST Adapter – JSON to XML conversion
This blog is part of a collection of blog entries that shows architectural concepts and configuration of the SAP PI REST Adapter. We also added some sample scenarios to make it easier for you to understand how your scenario can be implemented using the PI REST Adapter.
If you haven’t done so far, best is to start with the very first blog PI Rest Adapter – Don’t be afraid within the blog series covering the concepts of the REST adapter. A complete list of all blog entries can be accessed from here PI REST Adapter – Blog Overview.
The current blog shows you along a sample scenario how to convert JSON to XML format and vice versa.
A travel agency likes to gather flight details from an airline calling the remote function module BAPI_FLIGHT_GETDETAIL, and expose this interface as RESTful service. The format of the RESTful service should be JSON and hence needs to be converted into XML format before mapped to the BAPI structure.
In the SAP Process Integration Designer perspective of the NetWeaver Developer Studio (NWDS), I have defined an Integration Flow with a REST sender channel, an operation mapping that maps the outbound XML format into the BAPI structure, and an RFC receiver adapter. The conversion from JSON to XML is done within the REST sender adapter.
In the following, let’s focus on how the sender adapter needs to be configured.
Configuring the REST sender adapter
Double-click on the sender channel of type REST, and switch to the General tab below the Adapter-Specific tab. As data format of the input message choose JSON from the drop down menu. Within PI, the format of the payload needs to be XML, so select the Convert to XML check-box.
A sample JSON input message looks as follows:
The two JSON elements Agency and FlightDetails are both on the very first level of hierarchy which is allowed for JSON however not for XML. XML messages can have one root element only. If the JSON payload is converted into XML, this would not comply with the XML specification. So, we need to add a wrapper root element to the converted XML structure. As Element Name and Element Namespace we enter the name and namespace of the message type of our outbound service interface, here flight_query with namespace http://demo/hh/rest/flights.
The scenario runs synchronously, so select Best Effort from the drop down menu of the Quality of Service.
The response of the BAPI call is in XML format within PI, the agency however expects the response being in JSON format. So, we choose JSON as data format of the output message, and select the check box Convert XML Payload to JSON. Furthermore we select the Strip Outer Element check box to remove the message type element from the XML payload.
Switch to tab Channel Selection, and select the Specify Endpoint check box. As custom static endpoint enter /demo/flight.
Switch to the REST Resources tab. Here, we stick to a static endpoint URL, so we just enter / as pattern.
Running the scenario
For testing the scenario you can use the Advanced REST Client Application in the Google Chrome browser. The endpoint URL of your RESTful service starts with http://<host>:<port>/RESTAdapter with host and port of the SAP PI system, followed by what you have defined in the sender channel, here /demo/flight.
Enter a sample JSON payload like the one above, and select the Send button.
The response of the service call provides the flight details such as destinations and schedule in JSON format.
In message monitoring, you can download the payload of the request and response assuming that you have switched on logging. You can see that for the request message the wrapper element, i.e., the message type element has been added.
The response in XML format also contains the message type as root element which is then removed when converted into JSON.
Further XML/JSON conversion rules
From release 7.31 SP17 / 7.4 SP13 / 7.5 SP01 onwards, further XML to JSON conversion rules are supported, see Converting XML/JSON – Advanced Adapter Engine – SAP Library. You can define so called custom XML/JSON conversion rules to overrule the automatic conversion in cases where the result is not as expected, such as forcing an arraytype although an item occurs only once, or changing the data type of an element.
In our specific case, we like to change the message format of the response as follows:
- We like to keep the outer root element, and add a prefix to the same
- The flight element should always be of type array even if it occurs only once
- The connection ID should be of type integer (as you can see above it is interpreted as string)
- The arrival time should be of type decimal; if the conversion fails, a default value should be set
- The duration should be of type string (as you can see above it is interpreted as integer)
So, in the channel configuration, we add the following rules:
- Select the Enable Namespace Mapping check box, and add a new rule. Here, as XML Namespace set http://demo/hh/rest/flights, and as value we simply enter the term Prefix.
- In the Custom XML/JSON Conversion Rules section, add a new rule to define the flight root element as array in any case. Maintain namespace and prefix as seen above in the xml schema, as name set the element name flight, and as array type choose yes. Alternatively, you can also choose 1 or true.
- Add another rule with name ConnID and type integer
- Add another rule with name arrivalTime and type decimal, as default set 12.00 (note, this doesn’t make any sense but I just like to showcase you the default option)
- Add another rule with name duration and type string
If you run the scenario again, the response looks as follows. The respective configuration settings and their impact on the response are highlighted in the corresponding color.
I hope this blog was helpful to understand the JSON conversion capabilities of the SAP PI REST adapter. If you like to learn more, check out the other blogs in the series, accessible from the main blog PI REST Adapter – Blog Overview.