1

I have an end point like this

/profiles/1

I want to get the profile whose id is 1 but at the same time increment the visited property by 1. The property comes as part of the object. Which HTTP verb I should be using to fetch the profile object with visited property incremented by 1.

Everytime a profile with id: 1 is fetched, the visited property will be incremented by 1.

Angad
  • 1,144
  • 3
  • 18
  • 39
  • What if you get `/profiles/1` twice? Do you get the same result? In other words, does the response include the `visited` property? – user803422 Sep 26 '19 at 06:49

1 Answers1

6

Which HTTP verb I should be using to fetch the profile object with visited property incremented by 1?

The GET method is meant to be used for data retrieval, so it's a candidate. Quoting the RFC 7231, the document that currently defines the semantics and contents of the HTTP/1.1 protocol:

4.3.1. GET

The GET method requests transfer of a current selected representation for the target resource. GET is the primary mechanism of information retrieval and the focus of almost all performance optimizations. [...]

The GET method is also defined as both safe (read-only) and idempotent (multiple identical requests with that method is the same as the effect for a single such request).

But it's still on the table. Again, quoting the RFC 7231 (highlights are mine):

4.2.1. Safe Methods

Request methods are considered "safe" if their defined semantics are essentially read-only; i.e., the client does not request, and does not expect, any state change on the origin server as a result of applying a safe method to a target resource. [...]

This definition of safe methods does not prevent an implementation from including behavior that is potentially harmful, that is not entirely read-only, or that causes side effects while invoking a safe method. What is important, however, is that the client did not request that additional behavior and cannot be held accountable for it. For example, most servers append request information to access log files at the completion of every response, regardless of the method, and that is considered safe even though the log storage might become full and crash the server. [...]

4.2.2. Idempotent Methods

A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request. [...]

Like the definition of safe, the idempotent property only applies to what has been requested by the user; a server is free to log each request separately, retain a revision control history, or implement other non-idempotent side effects for each idempotent request.

Assuming you want to count the number of the times a profile is retrieved, then it makes sense to attach it to the GET operation. You may want, however, to avoid incrementing the counter when the endpoint is hit by a bot, for example.

So under certain conditions, GET requests are allowed to have side effects. What is important, however, is that the client did not request that additional behavior and cannot be held accountable for it: what a server does is the server's responsibility.

Ultimately, it's also important to say that HTTP doesn't care about the storage underneath, so you could either store the view count in the same table as the profile data or a different table or a completely different database. And then retrieve all together or use different endpoints for the view count.

Community
  • 1
  • 1
cassiomolin
  • 124,154
  • 35
  • 280
  • 359
  • @cassiomolin- thanks for the response. I was thinking the same that it should be GET but have some doubts - If we are updating the property on the object which is in the database in the same table then it means the GET operation is also updating the record in the db. In this case, is GET operation correct? Also, the guidelines state that GET operation is Idempotent. Does that mean update to visited property can still be done in the GET operation? – Angad Sep 19 '19 at 16:07
  • thanks for updating the answer. Just to be clear on the final statement you mentioned "Finally, assuming you want to count the number of the times a profile is retrieved, then it makes sense to attach it to the GET operation." I am actually reading the profile itself which will have a count property incremented by 1 every time a profile is fetched. The end point is to read a profile and not a count but reading the profile gives the count also incremented by 1 always. so GET still applies right ? – Angad Sep 20 '19 at 09:50
  • @Angad I've updated my answer to address your concerns. – cassiomolin Sep 20 '19 at 11:13
  • thanks for the update. One last question, reading the definition of the idempotent in http - what do you mean by "only applies to what has be requested by the user". What you mean by state of the resource when you say - "idempotency is about the effect produced on the state of the resource on the server and not about the response status code received by the client." – Angad Sep 20 '19 at 13:16
  • 2
    @Angad _"idempotency is about the effect produced on the state of the resource on the server and not about the response status code received by the client"_. It's a quote of my [other answer](https://stackoverflow.com/a/45019073/1426227). I meant to say that idempotency is about the state of the resources on the server and not about the status code. Consider a client performs a `DELETE` request to delete a resource. The resource gets deleted and the server returns `204`. Then the client repeats the same `DELETE` request and, as the resource has already been deleted, the server returns `404`. – cassiomolin Sep 23 '19 at 08:50
  • 2
    @Angad The `DELETE` request is idempotent as the effect of single request (remove a resource) is the same as the effect of multiple requests, despite the different status code. – cassiomolin Sep 23 '19 at 08:50
  • 2
    @Angad _"the idempotent property only applies to what has been requested by the user"_ It's a quote from the [RFC 7231](https://tools.ietf.org/html/rfc7231), which defines what idempotency is. While a client is requesting a representation of a profile (using `GET`, which is both safe and idempotent), the client should expect no side-effects, as the client did not request any additional behavior and cannot be held accountable for it. However, in the case of the profile view counter, the server may increment the counter as part of the semantic of the profile resource. – cassiomolin Sep 23 '19 at 09:06