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

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

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

是RPC吗?RPC和REST之间的区别是什么?


当前回答

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

REST的一个约束是它必须是无状态的。如果你有一个会话,那么你就有一个状态,所以你不能把你的服务称为RESTful的。

事实上,您在URL中有一个操作(即getAllData)是对RPC的指示。在REST中,您交换表示,您执行的操作由HTTP谓词指定。同样,在REST中,内容协商不是使用?p={JSON}参数执行的。

不知道您的服务是否是RPC,但它不是RESTful的。你可以在网上了解它们的区别,这里有一篇文章可以让你开始:揭穿RPC和REST的神话。您更了解服务内部的内容,因此将其函数与RPC进行比较,并得出自己的结论。

其他回答

因此,我认为:

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

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

归根结底,这是关于行为的哪一方拥有/持有数据。是的,您可以使用REST语言与基于RPC的系统进行通信,但是在这样做的时候仍然会执行RPC活动。

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

Example 2: I need to do a lot of complex math. I don't want to load a bunch of math methods into my object, I just want to pass some values to something else that can do all kinds of math, and get a result. Then RPC style makes sense, because the math object/entity will expose to my object a whole bunch of operations. Note that these methods might all be exposed as individual APIs and I might call any of them with GET. I can even claim this is RESTful because I am calling via HTTP GET but really under the covers it is RPC. My entity owns/holds the data, the remote entity is just performing manipulations on the copies of the data that I sent to it.

在HTTP上,它们都只是HttpRequest对象,它们都期望返回一个HttpResponse对象。我认为人们可以继续用这种描述来编码,而不用担心其他的事情。

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

例子:餐厅管理

REST的用例:订单管理

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

对于资源管理,REST是干净的。一个具有预定义操作的端点。这可以看作是一种向世界公开DB (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.

框架示例:Flask for python

REST最好被描述为与资源一起工作,而RPC更多地是关于操作。

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

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

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

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

这个端点执行一个特定的操作。

RPC

POST https://localhost:8080/sendOutageEmails

BODY: {"message": "we have a scheduled system downtime today at 1 AM"}

REST

POST https://localhost:8080/emails/outage

BODY: {"message": "we have a scheduled system downtime today at 1 AM"}

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

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

RPC

POST https://localhost:8080/saveBookDetails

BODY: {"id": "123", "name": "book1", "year": "2020"}

REST

POST https://localhost:8080/books

BODY: {"id": "123", "name": "book1", "year": "2020"}

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

总而言之,

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