Rest – Incorporate a background job enqueue endpoint in a REST API

api-designArchitecturedesignrest

To exchange data between our standalone frontend application and the backend API, we currently have a REST API, with standard endpoint to list/create/update/destroy ressources with a consistent naming and appropriate routes e.g for users:

GET /api/v1/users: list all users
GET /api/v1/users/{id}: return a specific user
POST /api/v1/users: create a user
PATCH /api/v1/users/{id}: update a user
DELETE /api/v1/users/{id}: destroy a user

However, our platform being a data processing tool, users can choose to start a task applying a certain operation to their data. The frontend will send a request to the backend in order to trigger the background job.

How should this fit in a REST API ? A background task is not a ressource as users or companies can be.
I have trouble finding a way to design a good API around launching background tasks or triggering events/messages that are not considered ressources.

How would you approach this ?

Best Answer

A background task is not a ressource as users or companies can be.

Fielding, when defining REST, offered this definition of a resource:

Any information that can be named can be a resource: a document or image, a temporal service (e.g. "today's weather in Los Angeles"), a collection of other resources, a non-virtual object (e.g. a person), and so on. In other words, any concept that might be the target of an author's hypertext reference must fit within the definition of a resource.

The fact that the underlying implementation is somehow different isn't relevant; on the contrary, part of the point of REST is that the facade insulates the client from the implementation details which might distinguish one resource from another.

How should this fit in a REST API ?

How would you start a task on a website? Presumably, there would be a link that clients could follow, which would lead to a resource that supported representation of a form; the form would describe the information required of the client as input fields. When the user submitted the form, the browser would use the form processing rules in the HTML specification to compose the request, using as a target uri whatever value was provided in the metadata of the form.

"Start a task" sounds like it wants unsafe semantics (you probably wouldn't want web spiders coming around starting tasks), so the form metadata would probably specify that the POST method be used.

The web client is just going to copy the form action into the HTTP request without examining or modifying it -- it is fundamentally opaque. So the server can use whatever identifier it wants for the form resource.

We might want "read your own writes", semantics; so if there were a resource that provided a "Most recent tasks" list, that would be a fine candidate for the target of the form, because generic HTTP compliant components will know to invalidate cached representations of a resource when the response includes a non-error status code.

The machines don't care which URI spelling conventions we use; but if we wanted identifiers that people can interpret (sometimes referred to as hackable URI), then we might have

GET /mostRecentTasks: see which tasks have been submitted recently
GET /newTaskForm: get the description of the form used to create new tasks
POST /mostRecentTasks: add a new task.

If you wanted to be more specific -- for instance, the most recent tasks for a particular user, you might instead do

/users/{id}/mostRecentTasks /users/{id}/newTaskForm

Where each user would have a form that submits requests to their own task list.

With that idea in mind; there's no rule that says you need to use POST. You could instead allow clients to use their favorite HTTP aware document editor to manipulate the mostRecentTasks representations directly, and send you a in turn a complete representation of their local copy (PUT), or a representation of the edits that they have made locally (PATCH).

Related Topic