据我所知,RESTful API中使用了四种方法:
GET用于获取资源.用于更新资源的
POST.
PUT用于创建或替换资源.
DELETE用于删除资源.
假设我们有一个名为apple的资源,我们可以通过多种方式"更新"它.例如,削减它,切片,或使其成为苹果汁.
这三种不同的更新操作中的每一种都采用不同的参数,并且其API中的常见部分将是:
POST /apple HTTP/1.1
Host: www.example.com
<different combination of arguments>
Run Code Online (Sandbox Code Playgroud)
在这种情况下,三个API共享相同的URI和相同的请求方法,它们的唯一区别是参数.我认为这迫使后端准备接受这些参数的联合集,并且为了区分实际请求的动作,后端需要检查参数的组合.它太复杂而且不优雅.
所以我的问题是:
在这个苹果案例中,如何设计出一套优雅的RESTful API,使后端可以轻松处理.
Ped*_*eck 16
首先,尽量避免将HTTP方法与CRUD操作混淆.我相信这是REST中混淆的主要原因.HTTP方法不会像这样干净地转换为CRUD操作.我在这里有一个详细的答案:
简而言之.
现在,在后端方面,尝试将REST资源更像是一个状态机,您可以使用这些方法来强制转换而不是使用方法的对象.这样您就可以将实现集中在资源本身上,而不是与协议的交互上.例如,您可以直接从方法的有效负载更改对象的属性,然后调用一个方法来检测所需的转换.
例如,您可能会认为苹果有三种状态,整个,削皮,切片和榨汁.您可以使用方法的标准化行为在状态之间转换.
例如:
GET /apple
{"state": "whole",
"self": "/apple"}
Run Code Online (Sandbox Code Playgroud)
然后你想要切片.你可以这样做:
PUT /apple
{"state": "sliced"}
Run Code Online (Sandbox Code Playgroud)
或者您可以执行以下操作:
PATCH /apple
{"from_state": "whole", "to_state": "sliced"}
Run Code Online (Sandbox Code Playgroud)
甚至是:
POST /apple
{"transition": "slice"}
Run Code Online (Sandbox Code Playgroud)
我们的想法是,实现可以是通用的,您不必过于担心将资源耦合到HTTP方法.
只要您的资源实现了解何时apple.state更改为其他内容,它应该检测到发生了哪些更改并执行适当的转换,您就完全脱离了协议.使用什么方法无关紧要.
我相信这是最优雅的解决方案,并使后端更容易处理.您可以实现您的对象,而无需过多担心协议.只要对象可以在状态之间转换,任何可以影响这些转换的协议都可以使用它们.
我的RESTful HTTP API与您的完全不同.我有:
GET用于获取的资源.
POST用于将新资源附加到集合.用于替换资源的
PUT(包括截断集合).
DELETE用于删除资源.用于更新资源的
PATCH.用于指示两个资源之间关系的
LINK.
UNLINK用于删除两个资源之间的关系.
"叶子"资源也可以被认为是一个集合.
例如,说你有/fruits,你POST一个apple到该集合资源,即回报
201 Created
Location: /fruits/apple
Run Code Online (Sandbox Code Playgroud)
以同样的方式,您可以将其/fruits/apple视为其属性的集合,因此:
GET /fruits/apple
->
colour=red&diameter=47mm
GET /fruits/apple/colour
->
red
GET /fruits/apple/diameter
->
47mm
Run Code Online (Sandbox Code Playgroud)
因此:
PUT /fruits/apple/slices
"12"
->
201 Created
GET /fruits/apple
->
colour=red&diameter=47mm&slices=12
Run Code Online (Sandbox Code Playgroud)
总而言之,我建议将您的操作表示为名词,并将这些名词定位为您要将操作应用到的资源的子资源.
| 归档时间: |
|
| 查看次数: |
15210 次 |
| 最近记录: |