Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Table of Contents
minLevel1
maxLevel4
outlinefalse
styledefault
typelist
printabletrue

Issues/Decisions

Introduction

There are few inconsistencies and missing features found within the CPS core APIs. This proposal aims to discuss these problems and suggest appropriate solutions for the same. The following list of APIs are found to be impacted by the findings:

  • Get a node

  • Update node leaves

  • Replace a node with descendants

Detailed Analysis

Get a Node

...

When a list is fetched using Get a node API then instead of returning a one list containing n-number of list nodesitems, the API returns n-lists containing one data node in each listJSON objects where each object contains one list item each.

For example: if there is a list named "Items" containing 10 items named Item 1, Item 2, ......, Item 10. Then when fetching this list is fetched using get a node API a total of 10 individual lists JSON objects are returned where each list object contains one Item, i.e. List 1→Item 1, List 2→ Item 2, ......., List 10→ Item 10.

...

.

Child pages (Children Display)
depth1
allChildrenfalse
style
sorttitle
first1
sortAndReversetitle
Expand
Data Originally Stored

...

Code Block

...

{
  "book-store:bookstore": {
    "bookstore-name": "Easons",
    "categories": [
      {
        "code": "1",
        "name": "Children",
        "books": [
          {
            "title": "Matilda",
            "lang": "English",
            "price": 20
          },
          {
            "title": "The Gruffalo",
            "lang": "English",
            "price": 15
          }
        ]
      }
    ]
  }
}

Response when querying the list directly

...

Code Block

...

[
  {
    "books": {
      "title": "Matilda",
      "lang": "English",
      "price": 20
    }
  },
  {
    "books": {
      "title": "The Gruffalo",
      "lang": "English",
      "price": 15
    }
  }
]

...

Expected Result

...

Code Block
[
  {
    "books": [
      {
        "title": "Matilda",
        "lang": "English",
        "price": 20
      },
      {
        "title": "The Gruffalo",
        "lang": "English",
        "price": 15
      }
    ]
  }
]

...

Initial setup to try the sample requests up ahead

To tryout the sample curl requests below please create a simple bookstore entry in your local CPS deployment. Or just execute the following curl request

true
Code Block
collapse
curl --location 'http://localhost:8883/cps/api/v2/dataspaces/my-dataspace/anchors/bookstore-example/nodes?xpath=%2F' --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'Authorization: ••••••' --data '{ "bookstore": { "bookstore-name": "Easons", "premises": { "addresses": [ { "house-number": 2, "street": "Main Street", "town": "Maynooth", "county": "Kildare" } ] }, "categories": [ { "code": 1, "name": "Children", "books" : [ { "title": "Matilda", "lang": "English", "authors": ["Roald Dahl"], "editions": [1988, 2000], "price": 20 }, { "title": "The Gruffalo", "lang": "English", "authors": ["Julia Donaldson"], "editions": [1999], "price": 15 } ] }, { "code": 2, "name": "Thriller", "books" : [ { "title": "Annihilation", "lang": "English", "authors": ["Jeff VanderMeer"], "editions": [2014], "price": 15 } ] } ] } } '

Update node leaves

Problem Description

When updating any data node, it's parent node xpath is provided as part of the update request. And the JSON payload contains the data of child node to be updated.

But if the JSON data of the parent node is provided due to a user error the parent nodes data can be sent as part of this the JSON payload and even then, then instead of failing , the request is successfully executed with partial update Where only the child data node is updated, and the parent data node is not updated.

...

Expand
Original JSON data:
JSON with updates
JSON data after update

Notes

Code Block
{
  "code": 1,
  "name": "Children",
  "books": [
    {
      "title": "Matilda",
      "lang": "English",
      "authors": ["Roald Dahl"],
      "editions": [1988, 2000],
      "price": 20
    }
  ]
}

Code Block

...

{
  "code": 1,
  "name": "Kids",
  "books": [
    {
      "title": "Matilda",
      "editions": 
		[1988, 2000, 2024],
      "price": 25
    }
  ]
}

Code Block

...

...

Problem Description 2

Update operation can only be done on one node at a time and when trying to update parent child in one request, then only the parent node is updated.

...

titleOriginal JSON data
collapsetrue

...

{
    "code": "1",
    "name": "Children",
    "books": [
      {
	 	"title": "Matilda",
        "lang": "English",
        "authors": ["Roald Dahl"],
        "editions": 
			[1988, 2000, 2024],
		"price": 25
       }
    ]
  }

...

  • It can be seen that the leaf data belonging to parent node i.e. code=1 is sent as part of JSON body. Where name is changed from Children to Kids
  • And the fields editions and price, of child node, i.e. title=Matilda are modified.
  • But after the request is executed only the child node is updated.
  • The expected behavior should be to throw an exception as the Update a node API requires parent node xpath to update any child data. Which in this case should be "/bookstore" because the request is also updating the node with key "code=1"
  • This situation can mainly occur due to user error, where user provides updated parent data along with parent node xpath as part of the request.

  • The expected behavior should be to throw an exception as the Update a node API requires parent node xpath to update any child data. Which in this case should be "/bookstore" because the request is also updating the node with key "code=1"

  • This situation can mainly occur due to user error, where user provides updated parent data along with parent node xpath as part of the request.

Curl request to replicate the scenario
Code Block
curl --location --globoff --request PATCH 'http://localhost:8883/cps/api/v2/dataspaces/my-dataspace/anchors/bookstore/nodes?xpath=%2Fbookstore%2Fcategories[%40code%3D1]' --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'Authorization: ••••••' --data '{
  "code": 1,
  "name": "Kids",
  "books": [
    {
      "title": "Matilda",
      "editions": 
		[1988, 2000, 2024],
      "price": 25
    }
  ]
}'

Problem Description 2

Update operation can only be done on one node at a time and when trying to update parent child in one request, then only the parent node is updated.

Expand
Original JSON data
JSON to be updated
Updated JSON data

Notes

Code Block
{
  "categories": {
    "code": "1",
    "name": "Children",
    "books": [
      {
	 	"title": "Matilda",
        "lang": "English",
        "price": 200,
        "authors":["Roald Dahl"],
        "editions": [1988,2000]
      }
    ]
  }
}

Code Block
{
  "categories": {
    "code": 1,
    "name": "Kids",
    "books": [
      {
        "title": "Matilda",
	 	"price": 20,
		"editions": 
		[1988, 2000, 2022]
      }
    ]
  }
}

Code Block
{
  "categories": {
    "code": "1",
    "name": "Kids",
    "books": [
      {
        "title": "Matilda", 
     	"lang": "English",
        "price": 200,
        "authors": ["Roald Dahl"],
		"editions": [1988,2000]        }
    ]
  }
}

  • So, either the API should reject any request containing multiple nodes or support updating multiple nodes at once.

Curl request to replicate the scenario
Code Block
curl --location --request PATCH 'http://localhost:8883/cps/api/v2/dataspaces/my-dataspace/anchors/bookstore/nodes?xpath=%2Fbookstore' --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'Authorization: ••••••' --data '{
  "categories": {
    "code": 1,
    "name": "Kids",
    "books": [
      {
        "title": "Matilda",
	 	"price": 20,
		"editions": 
		[1988, 2000, 2022]
      }
    ]
  

...

titleJSON to be updated
collapsetrue

...

}
}'

Replace a node with descendants

Problem Description

If a replace operation is performed on a list, where a new list item is also added to the list, then it results in a 200-response code, with a partial replace operation.

Expand
Original JSON data
Data to replace
Result after Replace operation

Notes

Code Block
[
  {
    "book-store:books": {
	  "title": "Matilda",
     

...

 "lang": "English",
  

...

   

...

titleUpdated JSON data
collapsetrue

...

 "price": 20,
      "

...

authors": ["

...

Roald Dahl"],
      "

...

editions": 

...

[1988,2000]
    }
  }
]

Code Block
{
  "books": [
    {
 

...

     "title": "Matilda",
      "

...

lang": "

...

English"

...

,
    

...

 

...

 

...

"

...

authors": ["

...

Roald Dahl"],
      

...

"

...

editions":

...

 [2024]
    },
    {
      "

...

title": 

...

"

...

The 

...

Gruffalo"

...

,
 

...

 

...

 

...

 

...

 

...

 "lang": "English",
   

...

  • The request is executed successfully but only a partial update takes place in the database.
  • So, either the API should reject any request containing multiple nodes or support updating multiple nodes at once.

Replace a node with descendants

Problem Description

If a replace operation is performed on a list, where a new list item is also added to the list, then it results in a 200-response code, with a partial replace operation.

...

titleOriginal JSON data
collapsetrue
   "authors": ["Julia Donaldson"],
      "editions": [1999],
      "price": 15
    }
  ]
}

Code Block
[
  {
    "book-store:books": {
	  "title": "Matilda",
      "lang": "English",
      "

...

authors": ["Roald Dahl"],
      "editions": [

...

2024]
    }
  }
]

...

titleData to replace
collapsetrue

  • This is a user error as request here is itself wrong, because it tries to add a new list element.

  • CPS provides a separate endpoint to Add a list element

  • So, such a scenario should be handled by the API instead of returning a successful response.

Curel request to replicate the scenario
Code Block
curl --location --globoff --request PUT 'http://localhost:8883/cps/api/v2/dataspaces/my-dataspace/anchors/bookstore/nodes?xpath=%2Fbookstore%2Fcategories[%40code%3D1]' --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'Authorization: ••••••' --data '{
  "books": [
    {
      "title": "

...

Matilda",
      "lang": "English",
      "authors": ["

...

Roald 

...

Dahl"],
      "editions": [

...

2024]
    },
  

...

 

...

titleResult after Replace operation
collapsetrue

...

 {

...


  

...

 

...

 

...

  "title": "

...

The Gruffalo",
      "lang": "English",
      "authors": ["

...

Julia 

...

Donaldson"],
      "editions": [

...

1999],
      "price": 15
    }
  

...

]
}'