REST API设计 - 在资源

时间:2016-08-08 17:12:48

标签: rest

假设我们有以下REST资源集合端点:

/products

资源如下所示:

GET /products/123
Accept: application/json

{
    "id": "123",
    "name": "Shampoo",
    ...
    "ingredients": [
        "Sodium Lauryl Sulfate",
        "Sodium Laureth Sulfate",
        "Hydrochloric Acid",
        ...
    ]
}

现在,让我们说我要更新资源,并在成分字段中添加或删除成分。 一种方法是GET资源,操纵数组,然后PUTPATCH。但是,这是非常繁琐的协议,如果数组太大,它也会造成可扩展性问题。

在没有源阵列的情况下实现此添加/删除操作的最佳方法是什么?

我已经探讨过以下内容:JSON Patch Specification 但似乎规范不是REST。它使用相同的资源,具有不同的"操作"像表示一样,它与资源的表示完全不同。

我希望PUT / PATCH方法尽可能保留与GET中显示的资源相同的表示形式。

以下是我对此事的看法。

  1. 字符串类型项更改为 object
  2. 将元字段添加到名为 $ op
  3. 的对象中

    因此,在此设计中,资源如何在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"
            }
        ]
    }
    

    有没有人有更好的方法?这个问题有一些标准吗?

1 个答案:

答案 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表示中删除成分数组并仅保留链接到它,您仍然可以立即添加新成分。

删除操作仍然需要源数组,但您可以异步下载它。事实上,我认为没有首先从数组中删除任何内容是没有意义的。你怎么知道你试图去除的成分在里面?

祝你好运