无状态计算的REST服务

4
我需要在我的REST API中创建一个方法,用于执行一些计算。为方便起见,假设我需要实现一个方法,对于给定的对象列表,将返回其长度。
它应该只计算长度并返回给客户端,因此不会服务器端修改任何资源。由于它不修改任何资源,人们期望它应该是一个GET请求。但是,由于列表可能很大,并且对象可能很复杂,因此看起来我需要将其作为POST请求。但是,这将违反POST在REST中用于创建资源的标准。
你对这个问题有什么解决方案?
3个回答

4

第一种解决方案

根据RESTful Web Services Cookbook,您可以将计算视为资源,只需使用GET获取即可。例如:

-- Request
GET /computations?param1=2&param2=2 HTTP/1.1

-- Response
HTTP/1.1 200 OK
Content-Type: application/json

{
    "result": 4
}

这听起来适用于具有少量输入参数的快速计算。但是如果您的计算不是那样,那么可以使用第二种解决方案。

第二个解决方案

将计算和结果都视为资源。对计算进行POST,对结果进行GET。例如:

首先创建一个计算

-- Request
POST /computations HTTP/1.1
Content-Type: application/json

{
    "param1": 2,
    "param2": 2
}

-- Response
HTTP/1.1 201 Created
Location: /computations/1

然后您可以获得这个计算。
-- Request
GET /computations/1 HTTP/1.1

-- Response
HTTP/1.1 200 OK
Content-Type: application/json

{
    "param1": 2,
    "param2": 2
}

同时,您还可以获取此计算的结果 (/computations/1/result)

-- Request
GET /computations/1/result HTTP/1.1

-- Response
HTTP/1.1 204 No Content
Cache-Control: max-age=3600,must-revalidate

但是糟糕的是!还没有结果。服务器告诉我们一个小时后再回来尝试 (Cache-Control: max-age=3600,must-revalidate)。第二种解决方案允许您使计算异步进行(在需要很长时间的情况下)或者您可以计算一次,将结果存储在某个数据库中,并在下一次请求时快速提供服务。

-- Request
GET /computations/1/result HTTP/1.1

-- Response
HTTP/1.1 200 OK
Content-Type: application/json

{
    "result": 4
}

看起来还不错,除了你没有在POST负载中传递ID => 服务器将自动分配一个ID,但是你怎么知道它是什么?它至少需要在响应负载中返回。想象一下,如果ID是一个哈希值,例如a12b43c98a,并且在计算资源创建后你没有在响应正文中得到它 :) - George Smith
感谢您发布这些解决方案。已为您的回答点赞。 - George Smith

3

实用回答:使用 POST

狡猾的回答:使用 POST。您的请求包含了一个资源(或一组资源),您希望服务器暂时创建这些对象的列表。如果服务器在成功处理POST请求后立即删除该资源,那有什么关系呢?


这个POST请求的响应会是什么?它将如何包含计算结果? - user1907906
嗯,这与REST原则不太一致。你所建议的是用POST来实现POST和DELETE :) - George Smith

1
这个故事的寓意是,使用REST时,即使实际上不需要资源并且很可能不会创建资源,你也始终假定存在一个资源。在上面的例子中,如果我既不想存储计算资源(由参数和某种操作组成的JSON对象),也不想存储计算结果资源,该怎么办?我不能。我只能够选择:
  1. 将其视为GET的虚拟资源(假装它存在);或者
  2. 使用单个POST创建两个资源 - 一个用于计算,另一个用于其结果 - 然后使用相应的GET来检索其中任何一个。
这里还有一个狡猾的假设,即/computation/<computaiton_id>/result没有POST,因为结果只能通过计算创建。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接