1

I have a system where logged in users can vote like or dislike on posts. If they try to like a post which has already been liked, they ll remove its vote. Same applies for dislike. As a REST newbie I am trying to come up with a url scheme for this and it is confusing

Currently, my urls look like this

POST /news/vote/social/:feedItemId/:vote(like|dislike|reset)

A single endpoint is doing everything and logged in users are the ones who can actually vote

After reading some other answers on stackoverflow it seems there are other possibilities as well like

PUT /news/vote/social/:feedItemId/(like|dislike)
DELETE /news/vote/social/:feedItemId

I have seen other answers where the userId is also included in the url because it says REST API design should not reflect statefulness

PUT /news/vote/social/feedItemId/:userId/(like|dislike)
DELETE /news/vote/social/:userId/:feedItemId

The problem with these urls is any person can update any userId s vote unless some backend check is involved

My question, is what is the right way to handle these considering only logged in people should be able to update only their vote?

PirateApp
  • 5,433
  • 4
  • 57
  • 90

1 Answers1

1

It sounds like you probably should take a look at Custom Methods.

Since this is a per-user action, it makes perfect sense to have custom methods that upvote and downvote, where each one acts as a toggle for +1 or -1. For example:

  • POST /items/1234:upvote on a new post would add +1 (points=1)
  • POST /items/1234:upvote on that same post again would take away the upvote (points=0)
  • POST /items/1234:downvote on that same post again would add -1 (points=-1)
  • POST /items/1234:downvote on that same post again would take away the downvote (points=0).

One extra consideration is the following sequence:

  • POST /items/5678:upvote would bring points to 1.
  • POST /items/5678:downvote right after would both take away the upvote and apply the downvote, bringing points from +1 to -1.

(and vice-versa for the reverse sequence)

You mention that this requires some back-end check, which is absolutely correct. If you implement your API where any user can apply upvotes or downvotes from any other user as long as they know the user ID, you've got a security risk. So the correct way to handle this is to use the back-end to pull the user ID from the session after they've signed in (and not from the URL where anyone can fill in the blank for which user they're voting on behalf of).

JJ Geewax
  • 10,342
  • 1
  • 37
  • 49