I'm designing a task queue rest interface and wondering about a best practice.
One action is to accept the "next" task in the queue.
By accepting the job only the first worker will get the job.
The worker won't know the task or the task id until accepting the job.
Now I'm thinking I can't use a GET because it's not idempotent. If calling nextTask two times you get two different jobs. So I guess it should be a POST.
POST //rest/taskqueue?action=acceptTask
Or am I looking at it the wrong way?
Basically:
This is how I would do it.
Enqueue a new task:
--> POST http://api.crazyjoes.com/v1/tasks/
--> {"data":{"lulcat":true}}
<-- 202 Accepted
Enqueue a new task with a specific ID:
--> PUT http://api.crazyjoes.com/v1/tasks/393ee7f6-c44a-4b34-86ac-92c9f31a4bc6/
--> {"data":{"lulcat":true}}
<-- 202 Accepted
Retrieve the oldest task:
--> GET http://api.crazyjoes.com/v1/tasks/oldest/
<-- 200 OK
<-- {"id":123,"data":{"lulcat":true}}
If the queue is empty:
--> GET http://api.crazyjoes.com/v1/tasks/oldest/
<-- 204 No Content
Dequeue a specific task:
--> DELETE http://api.crazyjoes.com/v1/tasks/123/
<-- 200 OK
<-- {"id":123,"data":{"lulcat":true}}
If the task has already been handled...
--> DELETE http://api.crazyjoes.com/v1/tasks/123/
<-- 410 Gone
If you want to dequeue the oldest item directly...
--> DELETE http://api.crazyjoes.com/v1/tasks/oldest/
<-- 200 OK
<-- {"id":123,"data":{"lulcat":true}}
How about:
/tasks
and /tasks/{taskId}
are the usual collection of all tasks and an individual task, respectively.
/tasksqueue
is the tasks on the queue, while /tasksqueue/top
is the top of the queue, and only supports a GET. Let's assume that all tasks have a unique id.
Then issue GET /tasksqueue/top
to get the id of the task at the top of the queue, and issue a DELETE /tasksqueue/{taskId}
to attempt to pop it off the queue.
If it fails, i.e. returns a non-20x, it means someone else popped the queue between your calls.
If it succeeds, it will return the task in its body and you can do what you want with it, knowing you've successfully popped it. Or since you know its id, you can get the task info from /tasks/{taskId}
.
It shouldn't succeed more than once.
And you can issue DELETE /tasksqueue/{taskId}
multiple times with the same overall effect on the system as just one of them, hence DELETE
is acting idempotently as it should. (The fact that all, or all but the first, DELETE
calls return a non-20x doesn't alter that fact.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With