0

I'm designing a restful API. In this API it's possible to POST, DELETE and GET cases using the API. If there is a case that you find particularly important its possible to put a "vote" on it so that a case becomes more prioritized.

However I am wondering what type of method this should be?

Which one should it be:

GET /cases/{case_id}/vote
POST /cases/{case_id}/vote
PUT /cases/{case_id}/vote

Calling the vote method will only increase the number of votes by 1. I'm currently leaning towards PUT myself seeing as how it's an update of an existing number (although POST could also be used for this) but I am wondering what the convention is.

Terabyte
  • 67
  • 6
  • http://stackoverflow.com/questions/630453/put-vs-post-in-rest This topic seems to have a good idea about what should be used but doesnt give a definitive answer in my case. – Terabyte Apr 29 '16 at 07:08

1 Answers1

3

First I would name the resource

/cases/{case_id}/votes

which makes it clear that this is the resource for the votes of the case.

Then use

POST /cases/{case_id}/votes

on this resource. On the server the count of votes would be increased by one.

Don't use PUT because this would mean that the client is in control of the total number of votes which is not correct. The client only triggers the increas by one, it is not setting the total number of votes.

  • 1
    for votes this isn't enough in my opinion as the current suggestion does not recognize multiple votes from the same client/user and therefore makes the vote somehow useless. Either the user/client needs to be added to the URI/resource or some other technique to allow only a single vote per user/client needs to be added – Roman Vottner Apr 29 '16 at 07:44
  • Yes, the server would be responsible to recognize a repeated vote from the same user. But that is not an API problem. –  Apr 29 '16 at 07:46
  • Letting the server keep track of the one-vote-per-user/client constraint is externalizing state to the server actually. As a poor-man approach the server could lock the IP address preventing further invocation of the URI for the respective client. If the server however is mirrored or behind a load-balancer who does not keep track of IP2Host connections a further request from the same client may be handled by a second server and thus still count as a second vote. Sure there are better techniques, though externalizing state to the server may not always be the best choice – Roman Vottner Apr 29 '16 at 07:57
  • What do you suggest as a solution? –  Apr 29 '16 at 07:58
  • If an authentication mechanism is used, the user/client can be extracted directly from the authenticated request and put into the resource (usually an own DB table like `user_vote`). Public votes may return the list of user who voted for something while private votes just return the vote count rather then the actual user. If no authentication mechanism is used (for whatever reason) you will need to either include the user/client (or token) in the URI, the headers or the actual resource you are sending to the server. The OP isn't specific enough on this TBH – Roman Vottner Apr 29 '16 at 08:09
  • These are good idea. I see nothing in them that conflicts with my answer about how the RESTful resources could be designed. –  Apr 29 '16 at 08:10
  • I wasn't arguing that your approach was wrong, I just annotated that for an actual voting system there needs a bit more then just a simple URI and made an example where a "RESTful" URI is simply not enough :) Though, the given information by the OP are also limited in first place – Roman Vottner Apr 29 '16 at 08:17
  • I understand that. But wouldn't then you comments be better placed on the question? –  Apr 29 '16 at 08:18
  • I haven't decided on how I am going to handle double votes. The cases can be posted with an API key (through an application). However, the application can serve multiple users and they make the cases (and it can be done anonymously). Whether or not I am gonna keep track of which application User is making a vote or not I have not yet decided. – Terabyte Apr 29 '16 at 08:23