Neilos
Neilos

Reputation: 2746

REST: deleting a resource from a collection using an implied ID as an input

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

Answers (1)

Evert
Evert

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:

  1. A client has access to the item via /items/{item_id}
  2. that item should have a link to /items/{item_id}/votes/{user_id}.
  3. The client uses that link to PUT or DELETE a vote.

Upvotes: 1

Related Questions