Patch packages deliver small updates or fixes to existing packages without requiring a full package reinstall. They typically address minor issues such as:
- Bug Fixes: Correcting package defects without introducing new features.
- Security Patches: Fixing vulnerabilities to prevent exploits or attacks.
- Performance Improvements: Optimizing existing functionality for better efficiency.
- Hotfixes: Urgent updates to resolve critical issues affecting users.
- Minor Enhancements: Small usability improvements or tweaks.
Patch packages allow for incremental updates to be applied efficiently.
The example packages used in the tutorial are the following:
| Base Package Example | Download the full example Recipe Manager application package here: Recipe Manager (Tutorial App).json |
|---|---|
| Patch Package Example | Download the patch package example here: Recipe Manager (Example Patch).json |
Patch Package Structure
The overall structure remains similar to a standard JSON package. However, a patch package requires additional properties that identify it as a patch package.
First, let’s take a look at a blank template for a patch package:
"package": {
"key": "",
"name": "",
"type": "patch",
"basePackageKey": "basePackageKey",
"dependsOn": [
{
"packageKey": "basePackageKey"
}
],
"runAfter": {
"packageKey": "basePackageKey"
},
"assets":
{
"...": [
{
"key": "",
"action": "",
...
}
]
}
}
The following properties define what kind of package it is and which package it modifies:
| Property | Purpose |
|---|---|
key | Unique key of the patch package. |
name | Name of the patch package, used mainly under the Resources > Packages section. |
type | Package type, specifies the package to be a patch. |
basePackageKey | Key of the package that this patch will modify. |
dependsOn | Key of the packages that the patch package depends on. This field is used in the case of multiple dependencies or to specify the base package version. |
runAfter | Array of keys of packages that must be installed first. Patch packages must run after the base package, otherwise the installation will not be successful. |
| To specify which assets or components will be modified, you must define both the key of the asset/component and the action to be performed. |
| Property | Purpose |
|---|---|
key | Identifies the asset or component the change applies to. |
action | Specifies how the asset or component changes using the action type. The what it modified is determined by the property’s position in the package. |
Patch Package Action Types
Different action types require different mandatory properties of the asset or component.
| Action | Mandatory Properties |
|---|---|
add | All mandatory properties have to be specified. |
delete | Only the key property of the modified asset or component is mandatory. |
update | The key property of the modified asset or component is mandatory, along with the properties that need updating. |
Action Property’s Position
The placement of the action property determines what will be modified.
Assets Level
Dawiso’s JSON editor will offer an optional action property to all assets which you can use to add, delete, or modify them. You can, for example, create new attribute types, add new translations, delete existing object types.
Example: Adding a new attribute type.
In our example, we will add a new attribute type which will store the calorie count. The value will be a number, which will also be sorted as an integer and not as a string. For more information, refer to the full list of attribute type features.
Click here to show the example.
"assets": {
"attributeTypes": [
{
"action": "add",
"key": "calories_count",
"name": "Calories Count",
"features": [
{
"key": "is_number"
},
{
"key": "sort_by_number"
}
]
}
]
},Property Level
Hidden action, also called referents, can be also applied at the property level action for a more granular patch. You can, for example, assign object types to an application, delete components from an object type template, or update attribute names.
Example 1: Assigning a newly created attribute to an object type.
Click here to show the example.
"objectTypes": [
{
"key": "recipe",
"attributeTypes": [
{
"action": "add",
"key": "calories_count"
}
]
}
]Example 2: Adding a new component to an object type template.
Click here to show the example.
"objectTypes": [
{
"key": "recipe",
"templates": {
"main": {
"rightArea": [
{
"action": "add",
"addToEnd": true,
"type": "panel",
"title": "title.panel.calories",
"values": [
{
"type": "attributes",
"values": [
"calories_count"
]
}
]
}
]
}
}
}
],Patch Package Structure Exceptions
Patching Components
Before applying a patch, ensure that all components used in the base package are defined in the components asset with:
- A unique key, so they can be modified.
- A component ID, which determines where new components will be added:
beforeComponentId, afterComponentId: Use the properties to determine the component’s precise position in the template.- If you don’t have component IDs defined, you can use these properties to add the component to the beginning or end of a template:
addToStartaddToEnd
When patching components, the entire component must be patched. The only exception is when modifying a component inside a panel, splitter, etc. (in other words, visual components).
Patching Arrays of Strings
If you need to modify an array of strings in the base package, the patch package must represent it as an array of objects. This allows each element to specify an action.
Example: Adding a new object type. Click here to hide the example.In the base package, object types are listed in an array of strings in the applications asset:
"applications": [
{
"key": "app",
...
"objectTypeKeys": [
"cuisine",
"recipe",
"ingredient_category",
"ingredient"
],
...
},
...
],In the patch package, we will need to specify keys of the object type we want to add, as well as the action in an array of objects.
"applications": [
{
"key": "app",
"objectTypeKeys": [
{
"action": "add",
"key": "new_objectType"
}
]
}
]