我正在设计一个任务队列休息界面并想知道最佳实践。
一个动作是接受队列中的“下一个”任务。
通过接受这份工作,只有第一个工人会得到这份工作。
工作人员在接受工作之前不会知道任务或任务 ID。
现在我想我不能使用 GET 因为它不是幂等的。如果调用 nextTask 两次,你会得到两个不同的工作。所以我想它应该是一个POST。
POST //rest/taskqueue?action=acceptTask
还是我看错了?
我正在设计一个任务队列休息界面并想知道最佳实践。
一个动作是接受队列中的“下一个”任务。
通过接受这份工作,只有第一个工人会得到这份工作。
工作人员在接受工作之前不会知道任务或任务 ID。
现在我想我不能使用 GET 因为它不是幂等的。如果调用 nextTask 两次,你会得到两个不同的工作。所以我想它应该是一个POST。
POST //rest/taskqueue?action=acceptTask
还是我看错了?
基本上:
我就是这样做的。
将新任务排入队列:
--> POST http://api.crazyjoes.com/v1/tasks/
--> {"data":{"lulcat":true}}
<-- 202 Accepted
将具有特定 ID 的新任务排入队列:
--> PUT http://api.crazyjoes.com/v1/tasks/393ee7f6-c44a-4b34-86ac-92c9f31a4bc6/
--> {"data":{"lulcat":true}}
<-- 202 Accepted
检索最旧的任务:
--> GET http://api.crazyjoes.com/v1/tasks/oldest/
<-- 200 OK
<-- {"id":123,"data":{"lulcat":true}}
如果队列为空:
--> GET http://api.crazyjoes.com/v1/tasks/oldest/
<-- 204 No Content
出列特定任务:
--> DELETE http://api.crazyjoes.com/v1/tasks/123/
<-- 200 OK
<-- {"id":123,"data":{"lulcat":true}}
如果任务已经处理...
--> DELETE http://api.crazyjoes.com/v1/tasks/123/
<-- 410 Gone
如果你想直接出列最旧的项目......
--> DELETE http://api.crazyjoes.com/v1/tasks/oldest/
<-- 200 OK
<-- {"id":123,"data":{"lulcat":true}}
怎么样:
/tasks
和/tasks/{taskId}
分别是所有任务和单个任务的通常集合。
/tasksqueue
是队列中的任务,while/tasksqueue/top
是队列的顶部,并且只支持 GET。让我们假设所有任务都有一个唯一的 id。
然后发出GET /tasksqueue/top
以获取队列顶部任务的 id,并发出 aDELETE /tasksqueue/{taskId}
尝试将其从队列中弹出。
如果失败,即返回非 20x,则意味着其他人在您的呼叫之间弹出队列。
如果成功,它将在其主体中返回任务,并且您可以对它做任何您想做的事情,因为您知道您已经成功弹出它。或者因为你知道它的 id,你可以从/tasks/{taskId}
.
它不应该成功不止一次。
DELETE /tasksqueue/{taskId}
并且您可以多次发出与其中一次相同的系统整体效果,因此DELETE
它应该是幂等的。(所有或除第一个之外的所有DELETE
调用都返回非 20x 的事实并没有改变这一事实。)
POST 是“追加”动词,也是 HTTP 规范中的“数据处理”动词。因此,从概念上讲,您将任务附加到任务列表以进行处理。POST 刚刚好。
GET 不正确的另一个原因是 GET 不应该对资源进行更改。但是传入的请求将进行更改……它将添加一项。
我会放弃“action=acceptTask”。在 REST 中,HTTP 动词指定您的意图,而 URI 指定目标。所以你正在做的是将一个新任务附加到队列中......“action”参数不会添加任何内容。
一般来说,如果你想为请求提供额外的信息,你可以添加参数来提供关于做什么的修饰符。但另一种约定是或多或少作弊,然后将意图放在 URI 的末尾,并将其视为子资源(即,而不是参数)。例如:
ht_p://.../taskqueue/fold
ht_p://.../taskqueue/roll
ht_p://.../taskqueue/rattle
(hm. not sure how many things you can actually do with a queue...)
但是,您永远不应该重复 HTTP 动词……这是对底层协议的滥用,也是 REST 中的禁忌:
ht_p://.../taskqueue/get
ht_p://.../taskqueue/update
ht_p://.../taskqueue/delete
...ack!