I want to add actions to my REST API that would move 'resources' between different 'stores'.
For instance, suppose my resources are normally accessed by the following URL:
/resources
/resources/{resourceId}
Now suppose I want to 'deactivate' some resource, i.e. conceptually move it to another sub-folder. The most straightforward way to allow this would be as followed.
'Deactivate' the resource, i.e. cause it to be unavailable under /resources. Conceptually, it 'moves' the object to the '/resources/deactivated/' subfolder:
POST /resources/{resourceId}/deactivate
Or alternatively:
POST /resources/deactivated/{resourceId}
Get all the deactivated objects:
GET /resources/deactivated
Reverse the 'deactivate' action, i.e. conceptually move the object from the '/resources/deactivated/' subfolder back to the main one ('/resources').
Either
POST /resources/{resourceId}/reactivate
Or
POST /resources/deactivated/{resourceId}/restore
This API seems rather intuitive for me. But it seems to violate the 'prefer nouns' rules that I have seen in many best practices-articles on REST API: I use verbs and adjectives instead of nouns!
Note that I might have parameters for all the endpoints, e.g. GET /resources/deactivated?createdBefore=01022017
Are there any better alternatives for my REST API? I.e. more RESTful, but not less intuitive ones?
Good resources that I could find on the topic:
First of all, remember that REST stands for Representational State Transfer.
It is all about resources and their state. Operations such as activate, deactivate and move are all about replacing the current state of the resource with a new representation and you don't need verbs in the URL to express such operations.
For example, to replace a status of a resource, you can send a new representation of the resource in the payload of a PUT
request:
PUT /api/resources/[id]/status HTTP/1.1
Host: example.org
Content-Type: application/json
{ "status" : "active" }
It can be understood as replace the status of the resource identified by [id]
with the one sent in the request payload.
Then you could have the following to get the resources with a particular status:
GET /api/resources?status=active HTTP/1.1
Host: example.org
Accept: application/json
It can be understood as give me a representation of all resources with the status active
.
To move a resource to another folder, for example, you could have:
PUT /api/resources/[id]/folder HTTP/1.1
Host: example.org
Content-Type: application/json
{ "target" : "draft" }
It can be understood as replace the folder of the resource identified by [id]
with the one sent in the request payload.