1

I'm building an api route which will pull data from our server. This data is sorted in an arbitrary (changing and unknown to the client manner), and will never return the same data more than once.

I'm currently thinking POST /resource/recommendation is the cleanest signature for this, but i'd like to hear others' thoughts.

  • 1
    If it's reading data and not changing it then it should normally be GET. Using POST would maybe keep crawlers from following it if that's what you want though you could do this with robots.txt I guess (if this is used on websites at all?). Also GET /resource/recommendations, so plural since several items are returned? (Personally I break the singular/plural rules sometimes e.g. when implementing a controller like /search). – thorsten müller May 26 '15 at 14:25
  • my reasoning for using POST was the fact that the resource itself is changing in a way. the data isn't impacted but calling that route again will get you different results every time, so it is neither idempotent nor safe. does that explanation change your answer at all – jtmarmon May 26 '15 at 14:31
  • 4
    Idempotency and safety as defined in RFC 7231 do not have anything to do with whether the returned result will be the same or not, and everything to do with side-effects triggered by the call - a safe call has no side effects, an idempotent calls has the same side-effects when made multiple times as when it is made a single time. Does pulling a recommendation change state on your server, in a way that the client cares about? If no state changes from the PoV of a user, I would be comfortable using GET. – jhominal May 26 '15 at 14:57
  • 1
    No, if you make a GET on a product and somebody else changes that product your next GET will not return the same product. It's not as if a GET would expect 100% identical results for each call. Ok, in this case the call itself has some kind of 'randomizing' side effect maybe (is this somehow stored on the server to ensure that no results are duplicate? This would be some kind of data manipulation at least). It makes it a bit tricky to decide but it seems not to change the resource as such and just have random effects. – thorsten müller May 26 '15 at 15:08
  • @jhominal pulling a recommendation means that the user cannot get that same piece of data back again. i.e. if they are recommended item A, the next time they call that route they are guaranteed to not get back item A again. – jtmarmon May 26 '15 at 19:02
2

Use GET.

The fact that the data changes each time a client accesses it is not a reason not to use GET. You are not POSTing any data to the web server, you are merely GETting the current state of the resource. That state may be constantly changing, for example GET /currenttime.html will constantly change each time you request it. There isn't anything in the HTTP spec that says that a client should expect that a resource does not change between GETs. The server can update the resource what ever way it sees fit, either internally or due to other clients updating the resource. A client should never assume that a resource has not changed since it last got its state.

It is though a reason to use an ETag in the response header to let the client (and any caching in between) know what the server has changed the resource since the client last accessed it. A client can compare the ETags to know that the resource has changed.

http://en.wikipedia.org/wiki/HTTP_ETag

  • thanks for the answer. would you still use the url /resource/recommendation for something like this? it's not very restful, but putting it at /resource conflates retrieving items based on some filtering/identifiers with retrieving a recommendation – jtmarmon May 27 '15 at 17:16
  • What does /resource/recommendation resource refer to? Is it recommendations for this resource? Or are you trying to say that the client recommended this resource if they GET that resource? Can you give an example? – Cormac Mulhall May 27 '15 at 19:01
  • it's recommendations for this resource. for example, /shoes/recommendations?limit=10 would return 10 shoes that the system thinks the user should wear. if invoked again, the user would get 10 new shoes (not returned previously) – jtmarmon May 27 '15 at 19:02
  • yeah that is fine, that is exactly the type of thing the query string is for. If you wanted to you could expand it to be /user/101/shoes/recommendations. That would be more correct as the resources after /user/101 refer only to that user. This isn't strictly necessary, but I think it is cleaner. – Cormac Mulhall May 27 '15 at 19:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.