Enhancing the Mapping by using XML Mapper for Advanced Scenarios
User Guide: Object Services > Stage 3: Mapping Operations to Back-end Methods > Enhancing the Mapping by using XML Mapper for Advanced Scenarios
Enhancing the Mapping by using XML Mapper for Advanced Scenarios
The core mapper engine is integrated into the Object Services pipeline. The mapper is an engine that logically takes in JSON, by using the declarative XML that it is passed, modifies the JSON, and creates nodes in the JSON and updates existing nodes.
For the request that is coming in to the mapper, after basic URL parsing and ODATA parsing are performed, all the context is made available to the request mapper. The request mapper modifies the payload and sends it into the next stage of the pipeline, which goes to the back end, typically by using an integration connector.
After the response is picked up, the whole context is made available to the response mapper. The Response mapper makes changes to the data, and outputs the data after some formatting. The internal mapper logic is the same for both the input and output pipelines, but the context that is made available to the mapper changes.
The following diagram shows the Object Services pipeline.
Request Mapper
On the input, when the mapper is applied, it is equivalent to the following.
mapper("input mapper xml", $current_input = data)
The $data is logically a blob with all the context made available to the mapper. You are passing in transformational XML to run on the current input. The mapper input can access any of the data that is passed to it.
request_in : Read-only, input payload JSON from API request.
request_out : Read-write, (a copy of input payload), transformed JSON that is sent to next stage.
vars : Empty. This is referenced using $vars and is used by mapper XML as a global variable store
- For more details, refer Simple Mapping example
Response Mapper
On the output, when the mapper is applied, it is equivalent to the following.
mapper("output mapper xml", $current_input = data)
The $data is logically a blob with all the context made available to the mapper.
response_in : Response from back end logically represented as JSON.
response_out : Transformed JSON using the XML mapper sent in the "records" field of the API response.
vars : Empty. This is referenced using $vars and is used by mapper XML as a global variable store.
- For more details, refer Simple Mapping example
Mapper Elements
The mapper includes the following built-in variables, built-in functions, and blocks.
Built-in Variables
**a/b/c** /* An input path of a.b.c in the given object */
**../b** /* inputpath = "b" on $current-input.getParent() */
**$current-input** /* Input instance of current map block */
**$current-output** /* Output instance of current map block */
**$mapper-input** /* Mapper instance’s global input */
**$mapper-output** /* Mapper instance’s global output */
**$vars/x** /* Variables are stored in this hash. All variables are GLOBAL */
**$args/<arg name>** /* Arguments passed to a function */
On a function call, by default, $args.current-input
is set to $current-input
, and $args.current-output
is set to $current-output
.
`input="myinput" inputpath="firstname"`
is equivalent to $myinput["firstname"]
inputpath="firstname"
is equivalent to $current-input["firstname"]
Input="3" /* not starting with a $, it is constant value. To use $ as a constant, use the escape character, for example, "\$".*/
output="$myoutput" outputpath="lastname"
is equivalent to $myoutput["lastname"]
Built-in functions
The Volt MX namespace contains a number of built-in functions that you can use with the mapper. The built-in functions are:
- equal
- concat
- substringBefore
- substringAfter
- choose-when-otherwise
- random
- min
- max
- sum
Note: The Volt MX namespace is reserved for VoltMX-defined functions only. User-defined functions cannot use the Volt MX namespace.
Blocks
The following table describes the blocks available:
Block | Description | Example |
---|---|---|
map | This is the main block in mapper. | |
set-param | Sets an output parameter from input. | |
set-arg | Variant of set-param to set the argument of a function. | |
set-variable | Variant of set-param to define and set a global variable. | |
exec-function | Execute function. The return value of exec-function is written to the output/outputpath attributes of exec-function. | /* Complex */ $vars[myresult] = field-map({a: "$current-input" ["firstname"], b: "3" }) |
choose-when-otherwise | When a "test" condition evaluates to true, then the "when" block is executed. If the "test" condition evaluates to false the "otherwise" block is executed. | |
Create-lookup | Create-lookup loops on the inputpath array and creates a hashmap with a lookup-key parameter as key and value as “Node” object refers to corresponding customer row of the input object. | |
Lookup | Retrieves the “Node” object from the hashmap and makes it available in the output. | |
Create-group | Create-group generates an aggregate group of objects based on a key designated by the group-key block. Each object is contains multiple entries. Each entry is a key/value pair. | |
Group-key | Key used to group items for aggregation. | |
javascript | JavaScript element must occur one time only as a child element to the Function element. Then name of outputpath attribute represents a field in the app data model. | |
script | The Script element is a required child element in a JavaScript element. It must occur one time only. The JavaScript snippet should be written in CDATA section of this element. |
Example: Mapper Structure
The following example shows the structure of the mapper in declarative XML.
<mapper xmlns="http://www.voltmx.com/ns/mapper"> /* root element */
<function name="field-map-a2b"> /* Function definitions */
<set-param />
<map input= output= inputpath= outputpath=></map>
</function>
<map input= output= inputpath= outputpath=> /* Mapper blocks */
<set-param input= inputpath= output= outputpath = />
<set-variable input= inputpath= output= outputpath= />
<exec-function name="field-map-a2b">
<set-arg />
</exec-function>
</map>
<map> </map> /* another map node */
</mapper>
Example: Simple Mapping
In this simple mapping example, the input is a list of records under A, and each record has P1 and P2 fields that we want to output to the API response by transforming P1 to Q1 and P2 to Q2.
The back end is returning columns by the name P1 and P2, where the object on the client side has fields named Q1 and Q2. For example, the backend could be returning FName and LName, and these are mapped to fields with more friendly names on the client side, Firstname and Lastname. The mapper, in each of the records it gets, picks up the value of P1, put it into a key of Q1 in the output.
The mapper is output-driven, so in the output, choose a path with the name A (outputpath="A"), and set up a parameter Q1 in output (set-param outputpath="Q1" inputpath="P1"), by taking the value from P1 from the input from a path with the name A (inputpath="A").
Input
{
"A": [
{
"P1": "value1",
"P2": "value2"
}
]
}
Output
{
"A": [
{
"Q1": "value1",
"Q2": "value2"
}
]
}
Mapping
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<mapper xmlns="http://www.voltmx.com/ns/mapper">
//"The following map tag for response or request"//
<map inputpath="response_in" outputpath="response_out">
<map outputpath="A" inputpath="A">
<set-param outputpath="Q1" inputpath="P1" />
<set-param outputpath="Q2" inputpath="P2" />
</map>
</mapper>
Identity Support in Mapper
The mapper can access identity security or profile attributes if they are needed by your service. For example, your service requires an input parameter that is available from the identity profile attribute.
To use identity support, follow these guidelines:
- The inputpath should be defined in the format “identity/
/ / " - In the defined structure, you must select either security or profile, depending on the specific identity token type that you want.
- Input should be defined as “$mapper-input”, which points to the mapper input node.
Example: Accessing the Identity Profile Attribute
The following example shows how to access the identity profile attribute using the mapper. The example is a request mapper that retrieves the value for the “PRODUCT” parameter from the “user_id” token of the “SAPIdentity” identity provider.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<mapper xmlns="http://www.voltmx.com/ns/mapper">
<map inputpath="request_in" outputpath="request_out">
<set-param inputpath="identity/SAPIdentity/profile/user_id" input="$mapper-input" outputpath = "PRODUCT "/>
</map>
</mapper>
Example: Accessing the Identity Security Attribute
The following example shows how to access the identity security attribute using the mapper. In this example, an identity security attribute value is mapped to a result parameter named "SAP-Session-Key-Value".
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<mapper xmlns="http://www.voltmx.com/ns/mapper">
<map inputpath="request_in" outputpath="request_out">
<set-param inputpath="identity/SAPIdentity/profile/user_id" input="$mapper-input" outputpath = "PRODUCT "/>
</map>
</mapper><?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<mapper xmlns="http://www.voltmx.com/ns/mapper">
<map inputpath="response_in" outputpath="response_out">
<map inputpath="Sample_Object" outputpath="Sample_Object">
<set-param inputpath="identity/SAPIdentity/security/VoltMXSAP-Session-Key" input="$mapper-input" outputpath="SAP-Session-Key-Value"/>
</map>
</map>
</mapper>
For more details on enhanced identity data-filtering, refer Enhanced Identity support in Object Services