JoAMoS
JoAMoS

Reputation: 1529

jsonpatch path to update array object by object ID

I am trying to figure out the best way to patch a collection of objects. I am trying to change the sort order of a number of objects and was thinking jsonpatch may be the right approach. My Object Looks Like:

[
  {
    "ID": "100",
    "FirstName": "John",
    "LastName": "Smith",
    "Email": "[email protected]",
    "SortOrder": 1
  },
  {

    "ID": "125",
    "FirstName": "John",
    "LastName": "Doe",
    "Email": "[email protected]",
    "SortOrder": 3
  },
  {

    "ID": "50",
    "FirstName": "james",
    "LastName": "johnson",
    "Email": "[email protected]",
    "SortOrder": 2
  },
]

I created an endpoint that allows a patch request to update multiple objects in the collection using jsonpatch request like this:

[
  {
    "op": "replace",
    "path": "/1/SortOrder",
    "value": 2
  },
  {
    "op": "replace",
    "path": "/0/SortOrder",
    "value": 1
  },
  {
    "op": "replace",
    "path": "/2/SortOrder",
    "value": 3
  }
]

What I want to be able to do is use the ID property in the jsonpatch path. Is that possible with my current object structure? It would look something like:

[
  {
    "op": "replace",
    "path": "/125/SortOrder",
    "value": 2
  },
  {
    "op": "replace",
    "path": "/100/SortOrder",
    "value": 1
  },
  {
    "op": "replace",
    "path": "/50/SortOrder",
    "value": 3
  }
]

What would I have to do to be able to make a patch request like this?

Upvotes: 20

Views: 23772

Answers (4)

Alessandro Scarozza
Alessandro Scarozza

Reputation: 4428

JSON Patch works exactly as your request if you change json from array to Map<ID, Object>

JSON Patch use index for array and key for map

Upvotes: 0

Anish Ramaswamy
Anish Ramaswamy

Reputation: 2351

You can avoid using arrays and just rely on JSON objects. It's not exactly ideal, but you can still rely on jsonpointers really nicely.

So your original document would change to look like:

{
  "100": {
    "ID": "100",
    "FirstName": "John",
    "LastName": "Smith",
    "Email": "[email protected]",
    "SortOrder": 1
  },
  "125": {
    "ID": "125",
    "FirstName": "John",
    "LastName": "Doe",
    "Email": "[email protected]",
    "SortOrder": 3
  },
  "50": {
    "ID": "50",
    "FirstName": "james",
    "LastName": "johnson",
    "Email": "[email protected]",
    "SortOrder": 2
  }
}

Then your JSON PATCH payload can look like:

[
  {
    "op": "replace",
    "path": "/125/SortOrder",
    "value": 2
  },
  {
    "op": "replace",
    "path": "/100/SortOrder",
    "value": 1
  },
  {
    "op": "replace",
    "path": "/50/SortOrder",
    "value": 3
  }
]

If you care about ordering in your JSON array, you can introduce a new field "position" or "index" or whatever you like to maintain ordering.

Upvotes: 1

bl2b
bl2b

Reputation: 121

try this function:

export function generateJsonPatch(obj: Object, patchObject = [], parent: string = null): Object[] {
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      if (obj[key] instanceof Object) {
        if (parent) {
          parent = parent + '/' + key;
        } else {
          parent = key;
        }
        generateJsonPatch(obj[key], patchObject, parent);
      } else if (obj[key]) {
        let fieldName;
        if (parent) {
          fieldName = parent + '/' + key;
        } else {
          fieldName = key;
        }
        const patchField = { op: 'replace', path: `/${fieldName}`, value: `${obj[key]}` };
        patchObject.push(patchField);
      }
    }
  }
  return patchObject;
}

// USAGE:
const test = {
  'a': '1',
  'b': '2',
  'c': [{
    'd': '4',
    'e': '5'
  }]
};

generateJsonPatch(test);
// it will generate
// [{ "op": "replace", "path": "/a", "value": "1" },
//  { "op": "replace", "path": "/b", "value": "2" },
//  { "op": "replace", "path": "/c/0/d", "value": "4" },
//  { "op": "replace", "path": "/c/1/e", "value": "5" }]

Upvotes: -4

Kipp
Kipp

Reputation: 741

Based on the Json pointer RFC, there is no way to select an element from an array by some property. Since JSON Patch uses JSON Pointer, you are out of luck.

It is too bad the JSON Patch folks didn't select JSON Path, or something similar, for the selection language.

Upvotes: 31

Related Questions