Patch Syntax

The texdp PATCH request expects a patch document as its payload. The format of the patch document is described in the JSON Patch standard RFC 6902. Please read the RFC for a complete description of what is available. A summary is provided in this section.

A patch document consists of a JSON array containing a series of entries. Each entry outlines an operation to be applied to a JSON document. The operations are performed sequentially to arrive at the final document.

Let’s start with an example. Consider the following JSON document:

{
  "baz": "qux",
  "foo": "bar"
}

If we apply this patch:

[
  { "op": "replace", "path": "/baz", "value": "boo" },
  { "op": "add", "path": "/hello", "value": ["world"] },
  { "op": "remove", "path": "/foo" }
]

the resulting JSON document is:

{
  "baz": "boo",
  "hello": ["world"]
}

JSON Patch uses a JSON Pointer to specify a path on which the operation will be performed. A JSON Pointer is a string of component names separated by a ‘/’. A component is either a property name for an object, or a number representing an index for an array. The special index ‘-’ may be used to represent appending to an array.

If you consider the JSON:

{
  "biscuits": [
    { "name": "Tim Tam" },
    { "name": "Teddy Bear" }
  ]
}

then /biscuits/1/name would refer to the value Teddy Bear, while biscuits/- can be used to add a value to the end of the biscuits array.

The general format of a patch operation is:

{
    "op": "{operation}",
    "from": "{path}",
    "path": "{path}",
    "value": "{value}"
}

Not all operations require all properties. For example, the add operation only requires the op, path and value properties.

The following operations are supported:

Add

Adds a value to a JSON object or inserts a value into an array. Where an array appears, the value is inserted before the given index. The special ‘-’ index is used to append values.

Using our biscuit example and applying the patch:

{ "op": "add", "path": "/biscuits/1", "value": { "name": "Tick Tock" } }

would result in:

{
  "biscuits": [
    { "name": "Tim Tam" },
    { "name": "Tick Tock" },
    { "name": "Teddy Bear" }
  ]
}

The add operation requires the op, path and value properties.

Remove

Removes a value from a JSON object or array. The path does not have to be to a leaf node. Some examples are:

{ "op": "remove", "path": "/biscuits" }
{ "op": "remove", "path": "/biscuits/0" }

where the first entry removes the biscuits object completely, including the property name, while the second removes Tim Tam from the biscuits array.

The remove operation requires the op and path properties.

Replace

Replaces an existing value with a new value. It is logically equivalent to performing a remove operation followed by an add. An example is

{ "op": "replace", "path": "/biscuits/0/name", "value": "Chocolate Mint" }

which replaces Tim Tam with Chocolate Mint.

The replace operation requires the op, path and value properties.

Copy

Copies a value from one location to another within the JSON document. An example is:

{ "op": "copy", "from": "/biscuits/0", "path": "/favourite" }

which results in:

{
  "biscuits": [
    { "name": "Tim Tam" },
    { "name": "Teddy Bear" }
  ],
  "favourite": "Tim Tam"
}

when applied to our original JSON document.

The copy operation requires the op, from and path properties.

Move

Moves a value from one location to another location. The operation is similar to a copy to the new location followed by a remove from the original location. An example is:

{ "op": "move", "from": "/biscuits", "path": "/cookies" }

which results in:

{
  "cookies": [
    { "name": "Tim Tam" },
    { "name": "Teddy Bear" }
  ]
}

when applied to our original JSON document.

The move operation requires the op, from and path properties.

Test

Tests that a specific value is set in the document. If the test fails, the whole of the patch is not applied. Using test you can restrict a patch to a set of documents that meet certain criteria. An example is:

{ "op": "test", "path": "/favourite/name", "value": "Tim Tam" }

which ensures that updates are only applied to records where the name of the favourite biscuit is Tim Tam.

A complex set of updates can be applied by providing a series of patch operations that are executed one after another. Once the patching is complete, the resulting record is checked against its schema to ensure it still meets any restrictions (e.g. required properties, etc.). If the record validates then it is saved in the system.

A PATCH operation takes effect on a record directly. The column name specified for changes does not require the leading data. path.

JSON Schema

The JSON Schema definition for JSON Patch is:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "$id": "emu:/shared/resources/patch#",
  "title": "JSON schema for JSONPatch files",
  "type": "array",
  "items": {
    "oneOf": [
      {
        "additionalProperties": false,
        "required": [ "value", "op", "path"],
        "properties": {
          "path" : { "$ref": "#/definitions/path" },
          "op": {
            "description": "The operation to perform.",
            "type": "string",
            "enum": [ "add", "replace", "test" ]
          },
          "value": {
            "description": "The value to add, replace or test."
          }
        }
      },
      {
        "additionalProperties": false,
        "required": [ "op", "path"],
        "properties": {
          "path" : { "$ref": "#/definitions/path" },
          "op": {
            "description": "The operation to perform.",
            "type": "string",
            "enum": [ "remove" ]
          }
        }
      },
      {
        "additionalProperties": false,
        "required": [ "from", "op", "path" ],
        "properties": {
          "path" : { "$ref": "#/definitions/path" },
          "op": {
            "description": "The operation to perform.",
            "type": "string",
            "enum": [ "move", "copy" ]
          },
          "from": {
            "$ref": "#/definitions/path",
            "description": "A JSON Pointer path pointing to the location to move/copy from."
          }
        }
      }
    ]
  },
  "definitions": {
    "path": {
      "description": "A JSON Pointer path.",
      "type": "string"
    }
  }
}