我有一个接受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

其他回答

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

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

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

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

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

例子:餐厅管理

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

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

最近我看到的大多数实现都是RPC,但许多人错误地将其称为REST。REST和HTTP是救世主,SOAP和XML是恶棍。所以你的困惑是合理的,你是对的,它不是REST。但是请记住,REST不是新事物(2000年),尽管SOAP/XML是旧的,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都可以使用 Level 3(RESTful):使用HATEOAS(超媒体链接)或者换句话说self 探索性的链接

三级(HATEOAS):

链接状态该对象可以这样更新,也可以这样添加。 链接状态这个对象只能被读取,我们就是这样做的。 显然,发送数据还不足以成为REST,但如何查询数据,也应该提到。但话说回来,为什么只有4个步骤呢?为什么不能只是步骤4,并将其称为REST呢?理查德森只是给了我们一个逐步实现的方法,仅此而已。

你们建立了可供人类使用的网站。但是你能不能 建立可以被机器使用的网站?这就是未来 rest式Web服务向您展示了如何做到这一点。

这本书RESTful Web服务很有帮助 一个非常有趣的阅读RPC vs REST

正如其他人所说,一个关键的区别是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.

共享的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。