用于更新对象图的REST API设计

Joh*_*ika 13 api rest object-graph

我正在设计一个REST API,我正在寻找更新对象图的推荐最佳实践.我的问题最好在一个例子中解释,所以让我说我有一个GET资源如下:

URI:/ people/123

此URI返回如下对象图:

{
    "name":"Johnny",
    "country":{"id":100,"name":"Canada"},
    "likes":[
        {"id":5,"name":"Fruit"},
        {"id":100,"name":"Sports"}
    ]
}
Run Code Online (Sandbox Code Playgroud)

当允许API使用者更新此资源时,您希望通过PUT或PATCH更新对象?更新"name"属性非常简单,但我不确定"country"或"likes",因为消费者只能改变与其他对象的关系而不能创建新对象.

以下是请求更新的一种方法:

{
    "name":"Bob",
    "countryId":200
    "likeIds":[3,10,22]
}
Run Code Online (Sandbox Code Playgroud)

此更新将资源更改为以下内容:

{
    "name":"Bob",
    "country":{"id":200,"name":"United States of America"},
    "likes":[
        {"id":3,"name":"Cars"},
        {"id":10,"name":"Planes"},
        {"id":22,"name":"Real Estate"}
    ]
}
Run Code Online (Sandbox Code Playgroud)

这种设计明确而明确地要求消费者只更新"人物"的"ID",但我担心PUT/PATCH的对象图看起来与GET不同,这使得API难以学习和记忆.所以另一种选择是按如下方式请求PUT/PATCH:

{
    "name":"Bob",
    "country":{"id":100},
    "likes":[
        {"id":3},
        {"id":10},
        {"id":22}
    ]
}
Run Code Online (Sandbox Code Playgroud)

这将产生与先前更新相同的更改,并且不会更改对象图.但是,API消费者并未明确只能更新"ID".

在这种情况下,建议采用哪种方法?

Cro*_*zin 9

在我看来,对于GET和PUT请求,你应该使用相同的结构.为什么?因为将JSON/XML数据映射到对象中是很常见的,并且如果JSON模式始终相同,那么执行实际映射的大多数(如果不是全部)软件最有效.

因此,您的Web服务应该接受以下JSON代码:

{
    "name":"Joe",
    "country":{"id":200,"name":"United States of America"},
    "likes":[
        {"id":5,"name":"Fruit"}
    ]
}
Run Code Online (Sandbox Code Playgroud)

但是,它不必考虑国家/地区名称,并且可能只关注国家/地区ID.