IDL is largely composed of the following key concepts: blocks, arrays, operators, conditional expressions, and function pipelines. Additionally, single line and multi-line comments are supported using //
and /*…*/
, respectively.
Blocks: Chunks of data organized in key-value pairs, contained within curly braces {…} and are analogous to JSON objects. Some blocks are named, such as the mapping
block within the IDL Mapping file, while unnamed blocks are considered “anonymous”. An expression configured for a specific field is considered an anonymous block.
Arrays: Lists of objects that are typically related in some way. For example, one of the arrays included in the Bulk Employee API data source is titled “WorkAssignments” and each object in the array contains an assortment of fields which, together, represent one work assignment. If an employee has three work assignments, the WorkAssignments array would have three objects, each with the same set of fields but different values, per the different work assignments on the employee record in Dayforce. Arrays in IDL are analogous to arrays in JSON.
Operators: Enable basic mathematical operations and logical operations that can link criteria in conditional expressions.
Types | Operators |
---|---|
Arithmetic |
Note: Standard operator precedence applies (PEMDAS). |
Logical |
Note: Standard Boolean operator precedence applies ( |
Conditional expressions: Allow testing conditions by using an if / else if / else
branching structure. All branches must return a value. In the example below, the Job
field includes a conditional expression which returns the BankName
if it exists; otherwise, it returns a static value of UnknownBank
.
mapping {
Root = map(source.Data, srcData => {
EmployeeNumber = srcData.EmployeeNumber ?? nil;
Job = if is_material(srcData.DirectDeposits.Items.BankName ?? nil) {
srcData.DirectDeposits.Items.BankName ?? nil
} else {
"UnknownBank"
};
});
}
Similarly, a conditional expression can validate two fields that are joined by the And
(&&
) logical operator before returning a result:
mapping {
Root = map(source.Data, srcData => {
EmployeeNumber = srcData.EmployeeNumber ?? nil);
Job = if is_material(srcData. DirectDeposits.Items.BankName ?? nil) && !is_material(srcData.DirectDeposits.Items.EffectiveEnd ?? nil) {
} else {
"UnknownBank"
};
});
}
Function pipelines: Replace traditional function notation for reading IDL expressions from left to right.
Traditional function notation is read from inside out. For example, f(g(h(x)))
is read in this order: perform operation h
on value x
, then perform operation g
on the result of operation h
, then perform operation f
on the result of operation g
.
However, IDL functions can be fed into each other using pipelines, which are composed of a pipe symbol and an angled bracket: |>
. Before the pipe, you must have either a value or a function that returns a value. The function after the pipe must accept the returned value as input.
Example: Assuming January 24, 2023 is the HireDate
, the following two expressions evaluate to the same result:
foo {
bar = date_add(HireDate, 2, "days")
|> format_date("MM/dd/yyyy"); // => "01/26/2023"
}
Instead of including HireDate
as input to the date_add
function, we can define the date using the date
function, then pass the result as input to the date_add
function using function pipelines:
foo {
bar = date(2023, 1, 24)
|> date_add(2, "days")
|> format_date("MM/dd/yyyy"); // => "01/26/2023"
}
Unknown, Empty, and Missing Values
Values included in IDL functions can be known, unknown, empty, or missing. IDL handles each value differently.
Known values are easy; when passed into a valid IDL, Integration Studio generates the expected result.
Unknown values are called NIL
. NULL
is traditionally used in place of an unknown value in computing systems. NIL
serves the same purpose in IDL. NIL
values fed into functions will have a nil (null) result. For example, the following expression would return a nil value if the SeniorityDate field is unknown in Dayforce:
date_add(SeniorityDate, 10, "years");
Values that are also containers, such as arrays and strings, can be empty. For example, an employee with no direct deposit records in Dayforce would have an empty <DirectDeposit>
array in the final output for the example outbound integration as follows:
Unlike empty values and unknown values (NIL and NULL), a missing value doesn’t exist at all. For example, if an employee in Dayforce has no middle name, the following function call would result in the field bar
being removed from the output:
foo = EmployeeNumber
bar = string_concat(FirstName, MiddleName, LastName);
If a function is missing a value, that missing value isn’t included in any results of that function. It’s also omitted from any other functions that use the original missing value.
If a value might be missing in the source, but the field should remain in the output regardless, or if other pieces of the expression must execute despite a missing value, the potentially missing value can be wrapped in a coalesce
function, which either returns the value if it exists or returns the default value provided:
foo = coalesce(EmployeeNumber, ReferenceCode)
bar = coalesce(string_concat(FirstName, MiddleName, LastName), nil);
Aggregations
Aggregations allow counts of records included in the integration, mainly for reporting counts of specific elements within the integration in headers and footers. For example, the IDL configuration below uses the count function to report on employee records, dependent records, as well as overall records:
mapping {
Root = map(source.Data, emp => {
id = emp.XRefCode;
name = emp.FullName;
@employeeCount = count();
@recordCount = count();
dependents = map(emp.Dependents, dep => {
name = dep.FullName;
@dependentCount = count();
@recordCount = count();
});
numberofEmployees = @employeeCount;
numberofDependents = @dependentCount;
totalNumberOfRecords = @recordCount;
});
}