Reputation: 2746
I have a resource:
/items
I want to allow users to vote on this resource both up and down
POST /items/{item_id}/votes
- to create a new vote passing in their + or - vote
I can get votes by (it uses logged in user's ID from access token to store votes with a key [item_id, user_id]
):
GET /items/{item_id}/votes
- to get all votes on an item
GET /items/{item_id}/upvotes
- to get all up votes on an item
GET /items/{item_id}/downvotes
- to get all down votes on an item
So votes
is a collection, but if I want to delete a vote completely should I use:
DELETE /items/{id}/votes
?? and delete based ont eh user's ID - but this resource refers to the collection I don't want to delete the whole collection, I do have enough info with the user_id and item_id to delete the vote but it doesn't seem right to me.
I can't directly refer to the user's vote at the moment so should I add an ID to each vote and:
DELETE /items/{item_id}/votes/{vote_id}
or maybe just:
DELETE /votes/{vote_id)
OR maye I don't need an ID on the vote and I can use:
DELETE /item/{item_id}/votes/mine/
- to delete an item from the collection using my logged in user_id
So to sumarise; what is the proper way to delete an item from a collection using REST via HTTP methods?
UPDATE
I have a feeling that these are the best solution
POST /items/{item_id}/votes
- to create a new vote using item_id and user_id (from access token)
DELETE /item/{item_id}/votes/mine/
- to delete my vote using item_id and user_id (from access token)
Upvotes: 2
Views: 51
Reputation: 99599
It depends a bit on how your collection looks like, but I assume if a vote is a downvote, it appears both in the downvotes
collection and in the votes
collection.
Both of these collections should link to this one vote, and ideally the vote (despite appearing in 2 collections) should have the same url in both.
To conform with REST you should indeed give the specific vote resource a specific url. If /items/{item_id}/votes/{vote_id}
is the unique path to the vote, DELETE
that and (as you said) not the collection.
So your other example:
DELETE /votes/{vote_id)
is also fine. If this is a globally unique vote_id, then that resource can still appear in post-specific downvotes
, upvotes
and votes
collections.
But this:
DELETE /item/{item_id}/votes/mine/
I personally would probably avoid. It's not super wrong, but the fact that you need mine
to appear in the url probably means your client is manually constructing the url and not discovering it. The actual url is mostly irrelevant.
Responding to your UPDATE
You also mention that every vote is tied to a "user_id". This means that you don't even need POST
to first create the vote. Just give the client the correct 'voting' url and PUT
your new vote resource. (remember that PUT
is generally better for creating resources because it's idempotent. POST
is typically only useful in cases where the new resource url cannot be determined by a client).
So these are the steps I would take:
/items/{item_id}
/items/{item_id}/votes/{user_id}
. PUT
or DELETE
a vote.Upvotes: 1