假设我们有以下REST资源集合端点:
/products
资源如下所示:
GET /products/123
Accept: application/json
{
"id": "123",
"name": "Shampoo",
...
"ingredients": [
"Sodium Lauryl Sulfate",
"Sodium Laureth Sulfate",
"Hydrochloric Acid",
...
]
}
现在,让我们说我要更新资源,并在成分字段中添加或删除成分。
一种方法是GET
资源,操纵数组,然后PUT
或PATCH
。但是,这是非常繁琐的协议,如果数组太大,它也会造成可扩展性问题。
在没有源阵列的情况下实现此添加/删除操作的最佳方法是什么?
我已经探讨过以下内容:JSON Patch Specification 但似乎规范不是REST。它使用相同的资源,具有不同的"操作"像表示一样,它与资源的表示完全不同。
我希望PUT
/ PATCH
方法尽可能保留与GET
中显示的资源相同的表示形式。
以下是我对此事的看法。
因此,在此设计中,资源如何在GET
GET /products/123
Accept: application/json
{
"id": "123",
"name": "Shampoo",
...
"ingredients": [
{
"name": "Sodium Lauryl Sulfate"
},
{
"name": "Sodium Laureth Sulfate"
},
{
"name": "Hydrochloric Acid"
},
...
]
}
现在,如果我想从 ingredients 数组中删除一个项目:
PATCH /products/123
Content-Type: application/json
Accept: application/json
{
"ingredients": [
{
"$op": "remove",
"name": "Hydrochloric Acid"
}
]
}
或者加回来:
PATCH /products/123
Content-Type: application/json
Accept: application/json
{
"ingredients": [
{
"$op": "add",
"name": "Hydrochloric Acid"
}
]
}
有没有人有更好的方法?这个问题有一些标准吗?
答案 0 :(得分:0)
在我看来,最好的解决方案是为产品成分管理提供另一个REST端点。当您另外以HATEOAS方式提供链接时,您将能够在获取产品资源后立即完全控制该阵列。
考虑这种表示:
GET /products/123
Accept: application/json
{
"id": "123",
"name": "Shampoo",
...
"ingredients": [
{
"name": "Sodium Lauryl Sulfate"
"links": [
{
"rel": "self",
"href": "/products/123/ingredients/1"
}
]
},
{
"name": "Sodium Laureth Sulfate",
"links": [
{
"rel": "self",
"href": "/products/123/ingredients/2"
}
]
},
...
],
"links": [
{
"rel": "self",
"href": "/products/123"
},
{
"rel": "ingredients",
"href": "/products/123/ingredients"
}
]
}
有了这个,你可以在产品中添加新成分......
POST /products/123/ingredients
Content-Type: application/json
Accept: application/json
{
"name": "Hydrochloric Acid"
}
...或删除现有的。
DELETE /products/123/ingredients/2
在没有源阵列的情况下实现此添加/删除操作的最佳方法是什么?
如果您从产品的JSON表示中删除成分数组并仅保留链接到它,您仍然可以立即添加新成分。
删除操作仍然需要源数组,但您可以异步下载它。事实上,我认为没有首先从数组中删除任何内容是没有意义的。你怎么知道你试图去除的成分在里面?
祝你好运