【问题标题】:Web service differences between REST and RPCREST 和 RPC 之间的 Web 服务区别
【发布时间】:2015-01-05 23:13:26
【问题描述】:

我有一个接受 JSON 参数的网络服务,并有特定的方法 URL,例如:

http://IP:PORT/API/getAllData?p={JSON}

这绝对不是 REST,因为它不是无状态的。它考虑了 cookie 并有自己的会话。

是 RPC 吗? RPC 和 REST 有什么区别?

【问题讨论】:

  • 为什么它是 REST 还是 RPC 很重要?你问的理由是什么?
  • 该服务不是我的,它声明它是 REST 但它似乎不是。我想知道我是否错了它不是 REST。
  • @Bogdan 知识是原因。
  • @Bogdan - 我担心讽刺的开始和递归的兔子洞,但你到底为什么要问他为什么问?
  • @glowkeeper:我想了解问题的上下文,知道如何更好地制定答案。

标签: web-services rest rpc


【解决方案1】:

您无法仅通过查看您发布的内容来明确区分 REST 或 RPC。

REST 的一个限制是它必须是无状态的。如果你有一个会话,那么你就有了状态,所以你不能调用你的服务 RESTful。

您的 URL 中有一个操作(即getAllData)这一事实表明对 RPC。在 REST 中,您交换表示,并且您执行的操作由 HTTP 动词指示。此外,在 REST 中,Content negotiation 不使用 ?p={JSON} 参数执行。

不知道你的服务是不是 RPC,但它不是 RESTful。您可以在线了解差异,这里有一篇文章可以帮助您入门:Debunking the Myths of RPC & REST。您更清楚自己的服务内部有什么,因此将其功能与 RPC 进行比较,然后得出您自己的结论。

【讨论】:

  • 所以 RESTful 意味着它在可能选择不遵守标准时遵守除 REST 之外的所有标准?。
  • @Mazmart:REST 是一组准则和约束。这不是一个可以实现的规范,并且当他们确实声称拥有 RESTful 服务时。据我所知,大多数时候人们将任何不是 SOAP 的东西称为 REST,而实际上只是某种其他类型的 RPC。
  • “揭穿 PRC 和 REST 神话”的链接将我转发到 Tyson Trautmann 的 Twitter 页面
  • @Jaidewani:我用存档中的一个替换了断开的链接,从写答案开始
  • Real-life-cutting-crap 示例:如何在 10000 个股票上请求 last_price ? GET 限制不允许。 POST 可以,但你打破了闪亮的学术 REST 理论。
【解决方案2】:

最好将 REST 描述为与资源一起使用,而 RPC 更多的是关于操作。

休息 代表代表性状态转移。这是一种组织独立系统之间交互的简单方法。 RESTful 应用程序通常使用 HTTP 请求来发布数据(创建和/或更新)、读取数据(例如,进行查询)和删除数据。因此,REST 可以将 HTTP 用于所有四个 CRUD(创建/读取/更新/删除)操作。

RPC 基本上用于跨不同模块进行通信以服务用户请求。 例如在 openstack 中,例如 nova、glance 和 neutron 在启动虚拟机时如何协同工作。

【讨论】:

    【解决方案3】:

    考虑以下 HTTP API 示例,该示例模拟了在餐厅下订单的情况。

    • RPC API 以“动词”的形式思考,将餐厅功能公开为接受参数的函数调用,并通过似乎最合适的 HTTP 动词调用这些函数 - 一个“get”查询,等等,但动词的名称纯粹是偶然的,与实际功能没有真正的关系,因为您每次都调用不同的 URL。返回代码是人工编码的,是服务合同的一部分。
    • 相比之下,REST API 将问题域中的各种实体建模为资源,并使用 HTTP 动词来表示针对这些资源的事务 - POST 用于创建,PUT 用于更新,GET 用于读。 在同一个 URL 上调用的所有这些动词提供不同的功能。常见的 HTTP 返回码用于传达请求的状态。

    下订单:

    检索订单:

    更新订单:

    示例取自sites.google.com/site/wagingguerillasoftware/rest-series/what-is-restful-rest-vs-rpc

    【讨论】:

    • 最后是一些 URL 示例。
    • 我不同意你所说的关于 URL 的说法。您可以在相同的 URL 上进行所有 RPC 调用,在不同的 URL 上进行 REST 调用。你只展示了硬币的一面。
    • 您在这里描述的不是 REST - REST 是一种架构模式。您所描述的是基于 HTTP 的 REST,这是大多数人在谈论 REST 时所想到的。
    • @basickarl 我不喜欢人们以不利的方式发表评论,但不以更好的方式回答。
    【解决方案4】:

    我会这样争论:

    我的实体是否持有/拥有数据?然后 RPC:这里是我的一些数据的副本,操作我发送给您的数据副本并将您的结果的副本返回给我。

    被调用实体是否持有/拥有数据?然后 REST:要么 (1) 向我展示你的一些数据的副本,要么 (2) 操纵你的一些数据。

    最终,它是关于操作的哪个“方面”拥有/持有数据。是的,您可以使用 REST 语言与基于 RPC 的系统对话,但这样做时您仍会进行 RPC 活动。

    示例 1:我有一个对象通过 DAO 与关系数据库存储(或任何其他类型的数据存储)进行通信。对我的对象和可以作为 API 存在的数据访问对象之间的交互使用 REST 样式是有意义的。我的实体不拥有/持有数据,但关系数据库(或非关系数据存储)拥有。

    示例 2:我需要做很多复杂的数学运算。我不想将一堆数学方法加载到我的对象中,我只想将一些值传递给可以进行各种数学运算的其他东西,并获得结果。那么 RPC 风格就有意义了,因为数学对象/实体将向我的对象公开一大堆操作。请注意,这些方法可能都作为单独的 API 公开,我可能会使用 GET 调用它们中的任何一个。我什至可以声称这是 RESTful,因为我是通过 HTTP GET 调用的,但实际上它是 RPC。我的实体拥有/持有数据,远程实体只是对我发送给它的数据副本执行操作。

    【讨论】:

      【解决方案5】:

      它是使用http的RPC。 REST 的正确实现应该不同于 RPC。拥有处理数据的逻辑,如方法/函数,就是 RPC。 getAllData() 是一种智能方法。 REST不能有智能,应该是外部智能可以查询的转储数据。

      这些天我看到的大多数实现都是 RPC,但很多人错误地将其称为 REST。带有 HTTP 的 REST 是救星,带有 XML 的 SOAP 是恶棍。所以你的困惑是有道理的,你是对的,它不是 REST。但请记住,尽管 SOAP/XML 很旧,但 REST 并不是新事物(2000 年),但 json-rpc 是后来出现的(2005 年)。

      Http 协议没有实现 REST。 REST(GET, POST, PUT, PATCH, DELETE) 和 RPC(GET + POST) 都可以通过 HTTP 开发(例如:通过 Visual Studio 中的 Web API 项目)。

      很好,那么 REST 是什么? 理查森成熟度模型如下(总结)。只有第 3 级是 RESTful。

      • 级别 0:Http POST
      • 级别 1:每个资源/实体都有一个 URI(但仍然只有 POST)
      • 2 级:POST 和 GET 都可以使用
      • 3 级(RESTful):使用 HATEOAS(超媒体链接)或换句话说 探索性链接

      例如:3 级(HATEOAS):

      1. Link 声明这个对象可以通过这种方式更新,也可以通过这种方式添加。

      2. Link 声明这个对象只能被读取,我们就是这样做的。

        显然,发送数据不足以成为 REST,但如何查询数据,也应该提到。但话又说回来,为什么是 4 个步骤?为什么不能只是第 4 步并称之为 REST? Richardson 只是为我们提供了一步一步的方法,仅此而已。

      您已经建立了可供人类使用的网站。但是你也可以吗 建立可供机器使用的网站?那是未来的地方 谎言,而 RESTful Web 服务向您展示了如何做到这一点。

      【讨论】:

      • 第一段以非常简单直接的方式解释了差异。有我的 +1 :)
      【解决方案6】:

      正如其他人所说,关键区别在于 REST 以名词为中心,而 RPC 以动词为中心。我只是想包含这个clear table of examples 来证明:

      ---------------------------------------+------------------------ -------------+-------------- 操作 | RPC(操作) | REST(资源) ---------------------------------------+------------------------ -------------+-------------- 注册 |发布/注册 |邮政/人 ---------------------------------------+------------------------ -------------+-------------- 辞职 |发布/辞职 |删除 /persons/1234 ---------------------------------------+------------------------ -------------+-------------- 读人 |获取 /readPerson?personid=1234 |获取 /persons/1234 ---------------------------------------+------------------------ -------------+-------------- 阅读个人物品清单 |获取 /readUsersItemsList?userid=1234 |获取 /persons/1234/items ---------------------------------------+------------------------ -------------+-------------- 将项目添加到人员列表 |发布 /addItemToUsersItemsList |发布 /persons/1234/items ---------------------------------------+------------------------ -------------+-------------- 更新项目 |发布/修改项目 |放置 /items/456 ---------------------------------------+------------------------ -------------+-------------- 删除项目 |发布 /removeItem?itemId=456 |删除 /items/456 ---------------------------------------+------------------------ -------------+--------------

      注意事项

      • 如表所示,REST 倾向于使用 URL 路径参数来标识特定资源
        (例如GET /persons/1234),而 RPC 倾向于将查询参数用于函数输入
        (例如GET /readPerson?personid=1234)。
      • 表中未显示 REST API 如何处理过滤,这通常涉及查询参数(例如 GET /persons?height=tall)。
      • 同样没有显示在任何一个系统中,当您执行创建/更新操作时,可能会通过消息正文传递附加数据(例如,当您执行POST /signupPOST /persons 时,您包含描述新人的数据)。
      • 当然,这一切都不是一成不变的,但它可以让您了解您可能会遇到什么,以及您可能希望如何组织自己的 API 以保持一致性。有关 REST URL 设计的进一步讨论,请参阅this question

      【讨论】:

      • 最好的解释,不那么冗长的 txt 和 url,并且清楚地传达了这一点。
      • +1。当我在阅读上面的答案时,我真的有一种感觉:哇,这些答案是用英文写的,但我就是看不懂他们在说什么。
      • 鉴于表中显示的差异,我们应该选择 RPC 而不是 REST 的任何特殊原因?例如,RPC 有更好的性能(如果是,为什么)?
      【解决方案7】:

      这是我在不同用例中理解和使用它们的方式:

      示例:餐厅管理

      REST 用例:订单管理

      - create order (POST), update order (PATCH), cancel order (DELETE), retrieve order (GET)
      - endpoint: /order?orderId=123
      

      对于资源管理,REST 是干净的。一个具有预定义操作的端点。可以看到一种向世界公开数据库(Sql 或 NoSql)或类实例的方法。

      实现示例:

      class order:
          on_get(self, req, resp): doThis.
          on_patch(self, req, resp): doThat.
      

      框架示例:用于 python 的 Falcon。

      RPC 用例:操作管理

      - prepare ingredients: /operation/clean/kitchen
      - cook the order: /operation/cook/123
      - serve the order /operation/serve/123
      

      对于分析性、操作性、非响应性、非代表性、基于操作的工作,RPC 效果更好,并且很自然地认为是功能性的。

      实现示例:

      @route('/operation/cook/<orderId>')
      def cook(orderId): doThis.
      
      @route('/operation/serve/<orderId>')
      def serve(orderId): doThat.
      

      框架示例:python 烧瓶

      【讨论】:

        【解决方案8】:

        通过 HTTP,它们最终都只是 HttpRequest 对象,并且它们都期望返回一个 HttpResponse 对象。我认为人们可以继续使用该描述进行编码并担心其他事情。

        【讨论】:

          【解决方案9】:

          这里有很多很好的答案。我仍然会将您推荐给this google 博客,因为它在讨论 RPC 和 REST 之间的差异方面做得非常好,并捕获了我在此处的任何答案中都没有读到的内容。

          我会从同一个链接中引用一段让我印象深刻的段落:

          REST 本身就是对支持 HTTP 和万维网的设计原则的描述。但由于 HTTP 是唯一具有商业重要性的 REST API,我们可以避免讨论 REST,而只关注 HTTP。这种替换很有用,因为人们认为 REST 在 API 上下文中的含义存在很多混淆和可变性,但对于 HTTP 本身的含义有更大的清晰度和一致性。 HTTP 模型是 RPC 模型的完美逆模型——在 RPC 模型中,可寻址单元是过程,而问题域的实体隐藏在过程之后。在 HTTP 模型中,可寻址单元是实体本身,系统的行为隐藏在实体后面,作为创建、更新或删除实体的副作用。

          【讨论】:

            【解决方案10】:

            共享的 URL 看起来像 RPC 端点。 下面是 RPC 和 REST 的示例。希望这有助于了解何时可以使用它们。

            让我们考虑一个向客户发送应用维护中断电子邮件的端点。

            此端点执行一项特定操作。

            RPC

            POST https://localhost:8080/sendOutageEmails
            
            BODY: {"message": "we have a scheduled system downtime today at 1 AM"}
            

            休息

            POST https://localhost:8080/emails/outage
            
            BODY: {"message": "we have a scheduled system downtime today at 1 AM"}
            

            RPC 端点更适合在这种情况下使用。当 API 调用执行单个任务或操作时,通常使用 RPC 端点。如图所示,我们显然可以使用 REST,但端点不是很 RESTful,因为我们没有对资源执行操作。

            现在让我们看看在数据库中存储一些数据的端点。(典型的 CRUD 操作)

            RPC

            POST https://localhost:8080/saveBookDetails
            
            BODY: {"id": "123", "name": "book1", "year": "2020"}
            

            休息

            POST https://localhost:8080/books
            
            BODY: {"id": "123", "name": "book1", "year": "2020"}
            

            REST 对于这样的情况(CRUD)要好得多。在这里,可以使用适当的 HTTP 方法来完成读取(GET)或删除(DELETE)或更新(PUT)。方法决定对资源的操作(在本例中为“书籍”)。 这里不适合使用 RPC,因为我们需要为每个 CRUD 操作(/getBookDetails、/deleteBookDetails、/updateBookDetails)设置不同的路径,并且必须对应用程序中的所有资源执行此操作。

            总结一下,

            • RPC 可用于执行单个特定操作的端点。
            • REST 用于资源需要 CRUD 操作的端点。

            【讨论】:

              猜你喜欢
              • 2010-11-29
              • 1970-01-01
              • 2017-01-06
              • 2013-09-24
              • 2012-03-19
              • 2017-10-02
              • 2014-11-28
              • 2011-11-16
              • 1970-01-01
              相关资源
              最近更新 更多