2

This is more a "philosophical" question than a technical one.

Assume that you have a message, and users that are allowed (or not) to access this message. Let's assume we have an api to do that, here would be the endpoints :

  • /message/(id_message)/allow/(user_id)
  • /message/(id_message)/forbid/(user_id)

Let's say now that, in addition to the HTTP status code, we have a field result_code that return a number that reflects exactly what happens in the code.

Let's say we allow the first time a user. The HTTP status code of this method should be 200, and let's say the result_code is 20.

If we straight call this method again, what should be the HTTP status code, the result_code, and why ?

2
  • HTTP 200 if the response is OK, 20 since it's the same method? Commented Oct 11, 2016 at 15:31
  • @Veve Well it would be 20 the first time but maybe 21 the second time as we already validated it and the front user might want to know Commented Oct 12, 2016 at 13:32

1 Answer 1

3

Surely this is not a philosophical question but one about what the standard says and about real advantages of obeying these standards.

HTTP specifies GET, PUT and DELETE operations to be idempotent. This means that repeating the call needs to have the same effect.

Making these operations idempotent is important because messages can get lost and the caller needs to have a way to handle that. There are no transactions in REST, so repeating an idempotent operation ensures that it is carried out when the caller is unsure whether the first call had an effect. In your example allowing a user twice should be the same as allowing it once.

RFC7231 defines idempotence as follows:

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. [...] Idempotent methods are distinguished because the request can be repeated automatically if a communication failure occurs before the client is able to read the server's response. [...] It knows that repeating the request will have the same intended effect, even if the original request succeeded, though the response might differ.

The server side (main) effect needs to be the same. The RFC allows the response to be different. Especially in the case of DELETE this is often the case as a successful deletion normally results in a 204 No Content and a repeated deletion results in a 404 Not Found.

Although responses needn't be identical, it is nevertheless helpful if they are. This simplifies client logic. The client can assume that a repeated call has the same effect so it should be able to handle it using the same code. The aforementioned exception with DELETE returning either 204 or 404 is quite common (as this simplifies server logic). Other exceptions are rare and should be only made if there is a good reason for that.

POST and PATCH operations are, strictly speaking, not required to be idempotent. Especially with PATCH it can be helpful, though.

POST operations are meant to be not idempotent. Or rather the other way around: If you have an operation that you cannot make idempotent, it should be a POST operation.

Speaking of standards and REST: A REST resource for the purpose mentioned by you should rather look like the following:

GET /messages/{messageId}/allowed-users

Returns the list of allowed users. Note that resources which represent lists are named in plural (so messages not message).

PUT /messages/{messageId}/allowed-users/{userId}

Add a new user to the list of allowed users.

DELETE /messages/{messageId}/allowed-users/{userId}

Revoke the right previously given.

All these operations should be idempotent.

Using a POST operation would look like the following:

POST /messages/{messageId}/allowed-users

{
    "userId": "1324"
}

POST adds a new element to a list-like resource. You are not required to make this idempotent but I'd consider is advisable in this case.

You can return additional result codes as a header or as a result object. Just as you mentioned. But if you like to: there were some folks who already thought about that in detail and came up with problem-detail.

Sign up to request clarification or add additional context in comments.

6 Comments

DELETE is idempotent? If I delete a resource I would expect a subsequent DELETE to the same resource to return a 404 - as it no longer exists.
@Gandalf According to RFC7231 DELETE should be idempotent, yes. But you are right, it is a common compromise to allow a subsequent 404, too.
You should be using the definition of idempotent as described in RFC7231 (section 4.2.2). It doesn't quite mean what you suggest.
@VoiceOfUnreason Thanks. I've improved my answer.
@R2C2 Thank you, so basically a request can be idempotent and return different HTTP status code (even body) at the same time ? As long as the request on the server side has the same effect of course. Although, having a result_code / problem-detail would still give a better understanding of what happened on the server side right ?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.