基于ID对OPA数组数据执行PATCH更新的方法咨询
问题描述
已将以下数据加载至OPA服务器:
{ "admin": [ { "id": 1, "action": "create", "object": "order" }, { "id": 2, "action": "read", "object": "order" } ], "user": [ { "id": 1, "action": "read", "object": "order" } ] }
需要基于ID更新特定记录,例如修改admin数组中id为2的对象的object字段,但尝试的PATCH请求报错:"message": "json: cannot unmarshal object into Go value of type []types.PatchV1",尝试的请求如下:
curl --location --request PATCH 'http://localhost:8181/v1/data/permission' \ --header 'Content-Type: application/json-patch+json' \ --header 'Authorization: Basic xxxxxxxxxxxxxxxx' \ --data '{ "admin": [ { "op": "test", "path": "/admin", "value": [{"id": 2}] }, { "op": "replace", "path": "/admin/1/object", "value": "test1" } ] } '
错误原因
你提交的请求违反了JSON Patch规范:JSON Patch要求请求体直接是一个操作数组,但你把操作嵌套在了admin对象中,导致OPA无法解析请求体,从而抛出类型不匹配的错误。
解决方案
修正请求格式,将操作直接放在顶级数组中,同时用test操作验证目标项的ID,避免误改:
curl --location --request PATCH 'http://localhost:8181/v1/data/permission' \ --header 'Content-Type: application/json-patch+json' \ --header 'Authorization: Basic xxxxxxxxxxxxxxxx' \ --data '[ { "op": "test", "path": "/admin/1/id", "value": 2 }, { "op": "replace", "path": "/admin/1/object", "value": "test1" } ]'
说明
- 顶级数组结构符合JSON Patch的格式要求,解决了解析错误
test操作用于验证/admin/1位置的对象id确实为2,防止因数组元素顺序变化导致误改其他项replace操作直接修改目标对象的object字段值
如果不确定目标元素的数组索引,可以先通过OPA查询获取位置:
curl --location --request POST 'http://localhost:8181/v1/query' \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic xxxxxxxxxxxxxxxx' \ --data '{ "query": "i := data.permission.admin[_]; i.id == 2; i" }'
该查询会返回id为2的admin对象及其在数组中的索引,拿到索引后替换上述Patch请求中的/admin/1即可。
内容的提问来源于stack exchange,提问作者Narayan bhat
相关产品推荐
相关产品推荐

