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

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

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

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


当前回答

考虑下面的HTTP api示例,该示例模拟餐厅中的订单。

The RPC API thinks in terms of "verbs", exposing the restaurant functionality as function calls that accept parameters, and invokes these functions via the HTTP verb that seems most appropriate - a 'get' for a query, and so on, but the name of the verb is purely incidental and has no real bearing on the actual functionality, since you're calling a different URL each time. Return codes are hand-coded, and part of the service contract. The REST API, in contrast, models the various entities within the problem domain as resources, and uses HTTP verbs to represent transactions against these resources - POST to create, PUT to update, and GET to read. All of these verbs, invoked on the same URL, provide different functionality. Common HTTP return codes are used to convey status of the requests.

下单:

RPC: http://MyRestaurant:8080/Orders/PlaceOrder (POST: {Tacos对象}) REST: http://MyRestaurant:8080/Orders/Order?OrderNumber=asdf (POST: {Tacos对象})

检索订单:

RPC: http://MyRestaurant:8080/Orders/GetOrder?OrderNumber=asdf (GET) 休息:http://MyRestaurant:8080/Orders/Order?OrderNumber=asdf (GET)

更新订单:

RPC: http://MyRestaurant:8080/Orders/UpdateOrder (PUT:{菠萝玉米饼对象}) REST: http://MyRestaurant:8080/Orders/Order?OrderNumber=asdf (PUT:{菠萝玉米饼对象})

示例取自sites.google.com/site/wagingguerillasoftware/rest-series/what-is-restful-rest-vs-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 api示例,该示例模拟餐厅中的订单。

The RPC API thinks in terms of "verbs", exposing the restaurant functionality as function calls that accept parameters, and invokes these functions via the HTTP verb that seems most appropriate - a 'get' for a query, and so on, but the name of the verb is purely incidental and has no real bearing on the actual functionality, since you're calling a different URL each time. Return codes are hand-coded, and part of the service contract. The REST API, in contrast, models the various entities within the problem domain as resources, and uses HTTP verbs to represent transactions against these resources - POST to create, PUT to update, and GET to read. All of these verbs, invoked on the same URL, provide different functionality. Common HTTP return codes are used to convey status of the requests.

下单:

RPC: http://MyRestaurant:8080/Orders/PlaceOrder (POST: {Tacos对象}) REST: http://MyRestaurant:8080/Orders/Order?OrderNumber=asdf (POST: {Tacos对象})

检索订单:

RPC: http://MyRestaurant:8080/Orders/GetOrder?OrderNumber=asdf (GET) 休息:http://MyRestaurant:8080/Orders/Order?OrderNumber=asdf (GET)

更新订单:

RPC: http://MyRestaurant:8080/Orders/UpdateOrder (PUT:{菠萝玉米饼对象}) REST: http://MyRestaurant:8080/Orders/Order?OrderNumber=asdf (PUT:{菠萝玉米饼对象})

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

正如其他人所说,一个关键的区别是REST url以名称为中心,而RPC url以动词为中心。我只是想包括这个清晰的例子表来证明:

---------------------------+-------------------------------------+--------------------------
 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       
---------------------------+-------------------------------------+--------------------------

笔记

As the table shows, REST tends to use URL path parameters to identify specific resources (e.g. GET /persons/1234), whereas RPC tends to use query parameters for function inputs (e.g. GET /readPerson?personid=1234). Not shown in the table is how a REST API would handle filtering, which would typically involve query parameters (e.g. GET /persons?height=tall). Also not shown is how with either system, when you do create/update operations, additional data is probably passed in via the message body (e.g. when you do POST /signup or POST /persons, you include data describing the new person). Of course, none of this is set in stone, but it gives you an idea of what you are likely to encounter and how you might want to organize your own API for consistency. For further discussion of REST URL design, see this question.

这里有很多很好的答案。我仍然建议你参考谷歌的这个博客,因为它在讨论RPC和REST之间的区别方面做得非常好,并抓住了一些我在这里的任何答案中都没有读到的东西。

我想引用同一链接中的一段话,这段话让我印象深刻:

REST itself is a description of the design principles that underpin HTTP and the world-wide web. But because HTTP is the only commercially important REST API, we can mostly avoid discussing REST and just focus on HTTP. This substitution is useful because there is a lot of confusion and variability in what people think REST means in the context of APIs, but there is much greater clarity and agreement on what HTTP itself is. The HTTP model is the perfect inverse of the RPC model—in the RPC model, the addressable units are procedures, and the entities of the problem domain are hidden behind the procedures. In the HTTP model, the addressable units are the entities themselves and the behaviors of the system are hidden behind the entities as side-effects of creating, updating, or deleting them.

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

例子:餐厅管理

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