RESTful API在同一个URI上执行多个操作时

就我所知,在RESTful API中使用了四种方法:

GET获取资源。
POST以更新资源。
PUT用于创建或替换资源。
删除以删除资源。

假设我们有一个名为apple的资源,我们可以通过几种方式“更新”它。 例如,削减它,切片或制作苹果汁。
这三种不同的更新操作中的每一个都有不同的参数,并且它们的API中的公共部分将是:

POST /apple HTTP/1.1
Host: www.example.com

<different combination of arguments>

在这种情况下,三个API共享相同的URI和相同的请求方法,唯一的区别是参数。 我认为这迫使后端准备好接受这些参数的联合集合,并区分实际请求哪个动作,后端需要检查参数的组合。 它非常复杂而不优雅。

所以我的问题是:
在这个苹果案例中,如何制定一套优雅的RESTful API,使后端可以轻松处理它。


首先,尽量避免将HTTP方法与CRUD操作相混淆。 我认为这是REST混乱的主要原因。 HTTP方法不会像这样干净地转换为CRUD操作。 我在这里有一个详细的答案:

S3 REST API和POST方法

简而言之。

  • POST是用于任何未通过HTTP标准化的操作的方法,并将有效负载置于目标URI。
  • PUT用于完全替换当前URI处的资源,并将有效负载置于服务本身。
  • PATCH用于部分幂等更新,在当前和期望状态之间有差异。
  • DELETE用于删除资源。
  • GET用于检索资源。
  • 现在,在后端,尝试将REST资源看作更像状态机,您可以使用这些方法强制转换,而不是使用方法对象。 这样您就可以将实现的重点放在资源本身上,而不是与协议的交互中。 例如,您可以直接从方法的有效负载中更改对象的属性,然后调用一个方法来检测需要进行的转换。

    例如,你可能会认为一个苹果具有三个状态,整个,削减,切片和榨汁。 您可以通过使用方法的标准化行为在状态之间转换。

    例如:

    GET /apple 
    
    {"state": "whole",
     "self": "/apple"}
    

    然后你想切片。 你可以做一些事情:

    PUT /apple
    
    {"state": "sliced"}
    

    或者你可以做一些事情:

    PATCH /apple
    
    {"from_state": "whole", "to_state": "sliced"}
    

    甚至像这样的东西:

    POST /apple
    
    {"transition": "slice"}
    

    这个想法是,这些实现可以是通用的,你不必担心将资源耦合到HTTP方法。

  • PUT版本是幂等的,所以你的客户可以选择在需要幂等性时使用它。
  • PATCH版本保证客户端知道当前状态并尝试有效的转换。
  • POST版本是最灵活的,你可以做任何你想做的事情,但需要详细记录。 你不能简单地假设你的客户会知道该方法的工作原理。
  • 只要你的资源实现了解到,当apple.state更改为其他内容时,它应该检测到发生了什么变化并执行了适当的转换,你完全脱离协议。 使用什么方法并不重要。

    我相信这是最优雅的解决方案,并且使后端更容易处理所有事情。 你可以实现你的对象而不用担心太多的协议。 只要对象可以在状态之间转换,任何可以影响这些转换的协议都可以使用它们。


    我的RESTful HTTP API与你的很不一样。 我有:

    GET获取资源。
    POST将新资源追加到集合。
    PUT代替资源(包括截断集合)。
    删除用于删除资源。
    用于更新资源的PATCH
    LINK用于指示两个资源之间的关系。
    UNLINK消除两种资源之间的关系。

    “叶子”资源也可以被认为是一个集合。

    例如,假设你有/fruits和您发布apple到该集合资源,即回报

    201 Created
    Location: /fruits/apple
    

    同样,您可以将/fruits/apple视为其属性的集合,因此:

    GET /fruits/apple
    ->
    colour=red&diameter=47mm
    
    GET /fruits/apple/colour
    ->
    red
    
    GET /fruits/apple/diameter
    ->
    47mm
    

    因此:

    PUT /fruits/apple/slices
    "12"
    ->
    201 Created
    
    GET /fruits/apple
    ->
    colour=red&diameter=47mm&slices=12
    

    因此,总而言之,我建议将您的操作表示为名词,并将这些名词定位为您要应用操作的资源的子资源。


    从资源角度考虑。 苹果是一种资源。

    要添加一个或多个苹果以列出“/苹果”,请使用POST。 REST风格允许发布数组。

    POST /apples HTTP/1.1
    Host: www.example.com
    

    现在假设你有一个ID为123的苹果。你可以使用方法GET在“/ apple / 123”上获得详细信息。

    GET /apples/123 HTTP/1.1
    Host: www.example.com
    

    要对苹果123进行任何更改,只需直接POST即可。

    PUT /apples/123 HTTP/1.1
    Host: www.example.com
    

    撇开它,切片或制作苹果汁 - 所有这些都基本上改变了苹果123的一些属性。正如你所说(正确),PUT不同属性的组合。

    链接地址: http://www.djcxy.com/p/40967.html

    上一篇: RESTful APIs when multiple actions on the same URI

    下一篇: Practice for finding a nested resource