delta
A delta
describes a modification to problem file.
They can be specified as part of a revision
and added to a sandbox via the Sandbox: Add Revision call.
A delta can be one of five types: array, dict,
keyed_array, object, or set.
object
and keyed_array
deltas can contain subdeltas, allowing a recursive tree of deltas to be applied.
Name | Type | Description |
---|---|---|
$collection | string | Required. Specifies the type of delta. Can be: array, dict, keyed_array, object, or set. Defaults to object . |
$path | string | Required on top-level deltas. The JSON path to modify. See Paths for a list of valid paths. |
Types
A delta
must be one of the following subtypes:
- array_delta - Modify an array where order is important; for example, route.jobs.
- dict_delta - Modify an object containing key-value pairs; for example, job.custom.
- keyed_array_delta - Modify an array where items can be identified by an ID field; for example, route.breaks.
- object_delta - Modify an object by recursively overwriting key-value pairs; for example, route or job.
- set_delta - Modify an array of unique strings; for example, job.required_route_attributes.
Paths
A delta can modify a problem file by using specific $path
values only.
Each $path
has a corresponding $collection
type that must be used with that path.
This ensures the problem remains canonical,
and ensures different API clients can identify modifications in a simple and reliable way.
The allowed set of paths is as follows:
- Root:
[]
-$collection
must beobject
- Jobs:
["jobs"]
-$collection
must bekeyed_array
- Drivers:
["drivers"]
-$collection
must bekeyed_array
- Routes:
["routes"]
-$collection
must bekeyed_array
- Schedules:
["schedules"]
-$collection
must bekeyed_array
- Route job sequence:
["routes", { "id": "<route0>" }, "jobs"]
-$collection
must bearray
. Replaceroute0
with the ID of the route to be modified. If the specified route ID does not exist, the problem file will not be modified. - Schedule job sequence:
["schedules", { "id": "<schedule0>" }, "jobs"]
-$collection
must bearray
. Replaceschedule0
with the ID of the schedule to be modified. If the specified schedule ID does not exist, the problem file is not modified.
A delta must never modify lower-level from higher-level paths.
For example, the route job sequence must never be modified via a delta to a route.
Instead these must be specified as two separate deltas in a revision.
This is to ensure that all route job sequence modifications can be identified by the $path
only, to make API development simpler.
Example
The following is an example of an invalid revision:
{
"deltas": [{
"$path": ["routes"],
"$collection": "keyed_array",
"assign": [
{
"id": "route0",
"name": "route0_newname",
"jobs": ["job0", "job1", "job2"] // This is invalid - cannot change a subpath
}
]
}]
}
The following is the same revision expressed in a valid manner:
{
"deltas": [{
"$path": ["routes"],
"$collection": "keyed_array",
"assign": [
{
"id": "route0",
"name": "route0_newname",
}
]
}, {
"$path": ["routes", { "id": "route0" }, "jobs"],
"$collection": "array",
"replace": ["job0", "job1", "job2"]
}]
}
Concurrency
It is possible for two revisions to be created independently by different API clients, and added to the sandbox at the same time. For that reason, it is important for revisions to be written defensively:
- $create should be set to
false
when doing an update. Otherwise, if a delete occurs before the update is applied, the update may become a create.
Performance
The UI applies deltas incrementally if they are added by another API client while a user has the sandbox open.
A delta sequence can be applied more efficiently when consecutive deltas have the same $path
,
as this allows the UI to perform batch processing.
Examples
Editing problem file settings
A revision to modify the settings and custom fields on a problem file:
{
"deltas": [{
"$path": [],
"settings": {
time_windows_as_hard_constraint: false,
},
"custom": {
"$collection": "dict",
"unassign": ["custom123"],
"move": { "old_name": "new_name" },
"assign": { "custom456": "789" },
},
}]
}
Modifying routes
A revision to modify two routes using an assign_template
:
{
"deltas": [{
"$path": ["route"],
"$collection": "keyed_array",
"ids": ["route0", "route1"],
"assign": {
"vehicle_type": "truck",
"driving_speed_percentage": null, // unset this field
"start_location": {
// Implicit "$collection": "object" means this will perform an assignment,
// and any existing fields on this object will be preserved
"location": "43.21,-172.34",
},
"load_capacities": {
"$collection": "keyed_array",
"key": "metric",
"assign": [{
"metric": "kg",
"amount": 123,
}],
},
"breaks": {
"$collection": "keyed_array",
"key": "id",
"assign": [{
"id": "lunch",
"start": "13:00",
}],
"unassign": ["dinner"], // bulk remove dinner break
},
"route_attributes": {
"$collection": "set",
"add": ["refrigeration"],
"remove": ["licenced"],
},
"custom": {
"$collection": "dict",
"assign": {
"custom_123": "456",
},
"move": {
"custom_rename_from": "custom_rename_to",
},
"unassign": ["custom_789"],
},
},
}]
}
Deleting jobs
A revision to delete two existing jobs:
{
"deltas": [{
"$path": ["job"],
"$collection": "keyed_array"
"unassign": ["job0", "job1"],
}]
}
Insert jobs into route
A revision to insert two jobs into a route:
{
"deltas": [{
$path: ["route", { id: "route0" }, "jobs"],
$collection: "array",
index: 3,
insert: [ "job3", "job5", "job7" ],
}]
}
Instantiating job on recurring schedule
A revision to create the 11th job in a schedule:
{
"deltas": [{
"$path": ["job"],
"$collection": "keyed_array",
"ids": ["job2"]
"assign": {
location: "marker1",
time_on_site: "00:10:00",
}
}, {
"$path": ["schedule", { id: "schedule0" }, "jobs"],
"index": 11,
"set": "job2",
}]
}
Replace route sequence
A revision to replace a route sequence, assign a base date, and save an address:
{
"deltas": [{
"$path": ["route", { id: "route0" }, "jobs"],
"$collection": "array",
"replace": ["job0", "job1", "job2"],
}, {
"$path": ["schedule"],
"$collection": "keyed_array",
"ids": ["schedule0"],
"assign": {
"base_date": "2010-09-13",
},
}, {
"$path": ["route"],
"$collection": "keyed_array",
"ids": ["route0"],
"assign": {
"location": {
"formatted_address": "123 Main St",
},
},
}]
}