Introduction
ONEiO uses an internal representation of messages that customers are sending between their systems.
The reason of having this internal canonical model is to make it easier to access the message data in a common way and to present the data to our users in a simplified way.
By default and for most use cases, the entity body structure, out of the box, is represented as the key-value body where routing rules and endpoint configurations are done with the dot notation but for more complex cases, we have another entity body structure called the Structured Body where routing rules and endpoint configurations are done with the slash notation.
This article first highlights the default key-value body structure, its uses cases and challenges encountered given a use case. Then the article goes further into the Structured Body topic, the reasons why it is needed, and how it solves the challenges with examples using the same use case cited earlier and then different ways of implementing this in your integration configurations.
TAKE NOTE
The structured body configuration must be added to the endpoint before any associated configurations in relation to this can be used in your integration. Please reach out to ONEiO support to enable this feature in the desired endpoint.
In case you have questions related to this subject, send a mail to support@oneio.cloud.
You can sign up for a free trial of ONEiO from the following link: ONEiO Free Trial
Overview
Default key-value body / Dot notation
To see the structure of your current message body, open a message and look for the "Received attributes" section. By default, this section will display:
- the familiar key-value style body structure.
- the use of dot notation in the received attributes.
Received Attributes - key-value body structure
View from "See all" modal window - Received attributes - key-value body structure
This is the original way message payloads are stored and it makes mapping between source and target messages easy. In most cases, this is sufficient for mapping in routing rules, for attributes in outbound mappings, attribute conditionals items and adding attributes under endpoint configuration in general.
Here's an example of a received XML message and the resulting key-value representation of it:
<Incident>
<Header>
<Id>INC-123</id>
</Header>
<Data>
<Description>Desc</Description>
</Data>
</Incident>
And here's the key-value representation of the payload. We call these key-values attributes with names and values:
Attribute name | Attribute value |
---|---|
Header.Id | INC-123 |
Data.Description | Desc |
As seen above, a dot-notation is used to represent the structure.
There are cases, however, where the messages have more complex hierarchical structures, with repeating elements, elements containing attributes, and more. Here's an example of a received XML message with a more complex hierarchical structure:
<Incident id="INC-123">
<Data>
<Description>Desc</Description>
<Person role="manager">
<email>jorma@example.com</email>
</Person>
<Person role="employee">
<email>orja@example.com</email>
</Person>
<ExtraData>
<Data>
<Name>foo</Name>
<Value>bar</Value>
</Data>
<Data>
<Name>baz</Name>
<Value>baa</Value>
</Data>
</ExtraData>
<Comments>
<Comment date="2018-08-17T09:45:43" user="User1">Some work notes 1</Comment>
<Comment date="2018-08-17T09:56:27" user="User2">Some work notes 2</Comment>
</Comments>
</Data>
</Incident>
The key-value presentation of this XML would look like this:
Attribute name | Attribute value |
---|---|
Data.Description | Desc |
Data.Person.email | jorma@example.com |
Data.Person.email | orja@example.com |
Data.ExtraData.Data.Name | foo |
Data.ExtraData.Data.Value | bar |
Data.ExtraData.Data.Name | baz |
Data.ExtraData.Data.Value | baa |
Data.Comments.Comment | Some work notes 1 |
Data.Comments.Comment | Some work notes 2 |
There are a couple of issues here with the current structure:
- The Incident ID is not available, because it's in an XML attribute and that's not supported using dot-notation structure
- What if we would like to map the email of a Person with role employee? We don't have that information available in the attribute names
- What if we would like to map the extra data that has Name of foo? It's not possible because the Name and Value end up into different attributes
- What if we would like to get the latest comment, i.e. the one with the newest date?
For instances similar to those mentioned earlier and more, depending on the use case in regards to any complex data structure we may receive, we offer the option of using a different kind of structure called Structured body (slash notation).
Structured Body / Slash Notation
INFO
The structured body configuration must be added to the endpoint before any associated configurations in relation to this can be used in your integration. Please reach out to ONEiO support to enable this feature in the desired endpoint.
To make it possible to handle more complex hierarchies, this is handled by a different entity body called the structured body. Structured body consists of a hierarchy nodes that have a name, value and attributes. This structure can be accessed with an XPath-like query syntax.
Received Attributes - Structured Body
View from "See all" modal window - Received attributes - Structured Body
Now using as a reference the previous XML example, here's how once again the received XML message and how one would configure the different data points or attributes with structured body:
<Incident id="INC-123">
<Data>
<Description>Desc</Description>
<Person role="manager">
<email>jorma@example.com</email>
</Person>
<Person role="employee">
<email>orja@example.com</email>
</Person>
<ExtraData>
<Data>
<Name>foo</Name>
<Value>bar</Value>
</Data>
<Data>
<Name>baz</Name>
<Value>baa</Value>
</Data>
</ExtraData>
<Comments>
<Comment date="2018-08-17T09:45:43" user="User1">Some work notes 1</Comment>
<Comment date="2018-08-17T09:56:27" user="User2">Some work notes 2</Comment>
</Comments>
</Data>
</Incident>
Data | Query |
---|---|
id | /Incident/@id |
Description | /Incident/Data/Description |
email of the Person in manager role | /Incident/Data/Person[@role="manager"]/email |
email of the Person in employee role | /Incident/Data/Person[@role="employee"]/email |
Value of foo ExtraData | /Incident/Data/ExtraData/Data[Name="foo"]/Value |
Value of baz ExtraData | /Incident/Data/ExtraData/Data[Name="baz"]/Value |
Latest comment (having biggest value in the date attribute) | /Incident/Data/Comments/Comment[@date=max(/Incident/Data/Comments/Comment/@date)] |
INFO
When used in Routing rule inbound attribute conditions and table mappings, we remove the enclosure ${}. In those cases, the syntax is the same as Query. More information on this under configuration methods and tips.
EXAMPLES WITH JSON:
EXAMPLE 1:
Let's look at this payload example of a received message in JSON format:
{
"contact": {
"firstName": "John",
"lastName": "Doe"
},
"issue": {
"fields": {
"labels": [
"Object",
"Item"
]
}
}
}
This is how the payload above will be represented in ONEiO UI using the Structured Body structure, under received attributes:
contact
firstName:"John"
lastName: "Doe"
issue
fields
labels
labels:"Object"
labels:"Item"
And this is how you can refer to/access this data:
Data | Query |
---|---|
firstName | /contact/firstName |
lastName | /contact/lastName |
labels with value ""Object" | /issue/fields/labels[labels="Object"]/labels |
labels with value ""Item" | /issue/fields/labels[labels="Item"]/labels |
With the example of /issue/fields/labels[labels="object"]/labels
The first part(/labels[labels="object"]) is essentially querying the data to check whether labels object exists, and the second /labels will point to the existing matched label element inside the first label element (it's read as /issue/fields/labels/labels).
EXAMPLE 2
With a received payload as seen below:
{
"request": [
{
"id": "1247fad",
"url": "https://www.example.org",
"rate": "591",
"speed": "720"
}
]
}
This is how the payload above will be represented in ONEiO UI using the Structured Body structure, under received attributes:
request
id:"1247fad"
url:"https://www.example.org"
rate: "591"
speed: "720"
And this is how you can refer to/access this data:
Data | Query |
---|---|
id | /request/[]/id |
url | /request/[]/url |
rate | /request/[]/rate |
speed | /request/[]/speed |
Xpath special characters
Some characters are part of Xpath syntax and depending on the position, they need to be escaped.
This payload example:
{
"request": {
"id": "123456",
"url": "https://www.example.org",
"detail": {
"@type": "oldcase"
}
}
Will be represented as the following using Structured Body format:
request
id:"123456"
url:"https://www.example.org"
detail
@type
And this is how to refer to the attributes above:
Data | Query | Syntax |
---|---|---|
id | /request/id | ${/request/id} |
url | /request/url | ${/request/url} |
value of @type | /request/detail/\@type | ${request/detail/\@type} |
CONFIGURATION METHODS AND TIPS
- All root attributes already present can remain the same as-is.
- When there is a need to update an attribute data type concerning how it is sent or received, a forward slash needs to precede the attribute and for each attribute level you add a slash (see examples below).
Adding to Endpoint configuration
- Just like in dot notation, referencing attributes with slash notation can be used on routing rules attribute conditions, outbound mappings, conversation variables and runtime variables. Here are a couple of examples of configurations in the UI - in edit and view mode:
Examples in Outbound mappings - edit view
Examples in Outbound mappings - view mode
Structured body attributes used in route information
INFO
Related articles : Advanced Message Feed, Routing rules
Comments
Please sign in to leave a comment.