我有一个Web服务,它接受JSON参数并具有方法的特定URL,例如:
http://IP:PORT/API/getAllData?p={JSON}
这绝对不是REST,因为它不是无状态的。它需要考虑cookie并拥有自己的会话。
是RPC吗? RPC和REST有什么区别?
答案 0 :(得分:44)
考虑下面的HTTP API示例,该API用于对放置在餐馆中的订单进行建模。
下订单:
检索订单:
更新订单:
取自sites.google.com/site/wagingguerillasoftware/rest-series/what-is-restful-rest-vs-rpc
的示例答案 1 :(得分:35)
仅通过查看您发布的内容,无法在REST或RPC之间明确区分。
REST的一个限制是它必须是无状态的。如果您有会话,那么您已拥有状态,因此您无法将服务称为RESTful。
您在网址中有一项操作(即getAllData
)这一事实表明了RPC。在REST中,您可以交换表示,并且您执行的操作由HTTP谓词决定。此外,在REST中,Content negotiation不会使用?p={JSON}
参数执行。
不知道您的服务是否为RPC,但它不是RESTful。您可以在线了解差异,这是一篇可以帮助您入门的文章:Debunking the Myths of RPC & REST。您更了解服务内部的内容,因此将其功能与RPC相比较,并得出您自己的结论。
答案 2 :(得分:7)
最好使用REST来描述资源,其中RPC更多地是关于操作。
<强> REST 强> 代表具象国家转移。这是组织独立系统之间交互的简单方法。 RESTful应用程序通常使用HTTP请求来发布数据(创建和/或更新),读取数据(例如,进行查询)和删除数据。因此,REST可以将HTTP用于所有四个CRUD(创建/读取/更新/删除)操作。
<强> RPC 强> 基本上用于跨不同模块进行通信以满足用户请求。 例如在openstack中,比如nova,glance和neutron在启动虚拟机时如何协同工作。
答案 3 :(得分:7)
它是使用http 的 RPC。 REST的正确实现应不同于RPC。具有逻辑来处理数据(例如方法/函数)的就是RPC。 getAllData()是一种智能方法。 REST无法提供智能,应该转储可以由外部智能查询的数据。
如今,大多数实现都是RPC,但是许多人错误地将其称为REST,因为他们看到它们没有使用XML / Soap,而是使用HTTP + json。使用HTTP的REST是拯救者,使用XML的SOAP是恶棍。因此,您的困惑是有道理的,而且您是对的,这不是REST。
Http协议未实现REST的实现。 REST(GET,POST,PUT,PATCH,DELETE)和RPC(GET + POST)都可以通过HTTP(例如,通过Visual Studio中的Web API项目)进行开发。
RPC很老,每个学校的孩子都知道RPC是什么,可以理解,大多数REST开发的最终都是RPC(HTTP + Json)。但是什么是REST? 理查森到期模型如下(概述)所示。只有3级是RESTful。
例如等级3:
您已经建立了可供人类使用的网站。但是你也可以 建立可供机器使用的网站?那是未来的地方 谎言,RESTful Web服务向您展示如何做到这一点。
答案 4 :(得分:7)
As others have said, a key difference is that REST is noun-centric and RPC is verb-centric. I just wanted to include this clear table of examples demonstrating that:
---------------------------+-------------------------------------+-------------------------- Operation | RPC (operation) | REST (resource) ---------------------------+-------------------------------------+-------------------------- Signup | POST /signup | POST /persons ---------------------------+-------------------------------------+-------------------------- Resign | POST /resign | DELETE /persons/1234 ---------------------------+-------------------------------------+-------------------------- Read person | GET /readPerson?personid=1234 | GET /persons/1234 ---------------------------+-------------------------------------+-------------------------- Read person's items list | GET /readUsersItemsList?userid=1234 | GET /persons/1234/items ---------------------------+-------------------------------------+-------------------------- Add item to person's list | POST /addItemToUsersItemsList | POST /persons/1234/items ---------------------------+-------------------------------------+-------------------------- Update item | POST /modifyItem | PUT /items/456 ---------------------------+-------------------------------------+-------------------------- Delete item | POST /removeItem?itemId=456 | DELETE /items/456 ---------------------------+-------------------------------------+--------------------------
Notes
GET /persons/1234
), whereas RPC tends to use query parameters for function inputsGET /readPerson?personid=1234
).GET /persons?height=tall
).POST /signup
or POST /persons
, you include data describing the new person).答案 5 :(得分:3)
我会这么说:
我的实体是否持有/拥有数据?然后RPC:这是我的一些数据的副本,操纵我发送给你的数据副本并返回给你一份你的结果。
被叫实体是否拥有/拥有数据?然后REST:要么(1)向我展示一些数据的副本,要么(2)操纵你的一些数据。
最终,该行动的“一面”拥有/保存数据。是的,您可以使用REST语句与基于RPC的系统进行通信,但在执行此操作时您仍将执行RPC活动。
示例1:我有一个通过DAO与关系数据库存储(或任何其他类型的数据存储)通信的对象。将REST样式用于我的对象和可以作为API存在的数据访问对象之间的交互是有意义的。我的实体不拥有/保存数据,关系数据库(或非关系数据存储)也是如此。
示例2:我需要做很多复杂的数学运算。我不想将一堆数学方法加载到我的对象中,我只想将一些值传递给可以进行各种数学运算的其他值,并获得结果。然后RPC样式是有意义的,因为数学对象/实体将向我的对象公开一大堆操作。请注意,这些方法可能都作为单独的API公开,我可以使用GET调用它们中的任何一个。我甚至可以声称这是RESTful,因为我通过HTTP GET进行调用,但实际上它是RPC。我的实体拥有/保存数据,远程实体只是对我发送给它的数据副本进行操作。
答案 6 :(得分:2)
这里有很多很好的答案。我仍然会推荐您访问this谷歌博客,因为它在讨论RPC和REST之间的区别方面做得非常好,并且捕获了我在此处的任何答案中都未读到的内容。
我会引用引人注意的同一段中的一段:
REST本身是对HTTP和万维网基础的设计原则的描述。但是,因为HTTP是唯一在商业上重要的REST API,所以我们几乎可以避免讨论REST,而只关注HTTP。这种替代很有用,因为人们认为REST在API上下文中的含义存在很多混乱和可变性,但是对于HTTP本身是什么却有更大的清晰度和共识。 HTTP模型是RPC模型的完美反面-在RPC模型中,可寻址单元是过程,而问题域的实体则隐藏在过程的后面。在HTTP模型中,可寻址单元是实体本身,系统的行为被隐藏在实体后面,这是创建,更新或删除它们的副作用。
答案 7 :(得分:1)
通过HTTP,它们最终都只是HttpRequest
对象,并且都希望返回HttpResponse
对象。我认为人们可以继续使用该描述进行编码,而不必担心其他事情。
答案 8 :(得分:1)
共享的 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 端点更适合在这种情况下使用。 RPC 端点通常在 API 调用执行单个任务或操作时使用。我们显然可以使用 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 方法来完成 read(GET) 或 delete(DELETE) 或 update(PUT)。方法决定对资源(在本例中为“书籍”)的操作。 在这里使用 RPC 是不合适的,因为我们需要为每个 CRUD 操作(/getBookDetails、/deleteBookDetails、/updateBookDetails)设置不同的路径,而且必须对应用程序中的所有资源都这样做。
总结一下,
答案 9 :(得分:0)
这就是我在不同用例中的理解和使用方式:
示例:餐厅管理
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的猎鹰。
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的烧瓶