0

Starting Point:

According to https://www.rfc-editor.org/rfc/rfc9110.html#name-safe-methods, when making a GET call, the client is not requesting and not expecting the call to lead to any state changes.

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.

Of the request methods defined by this specification, the GET, HEAD, OPTIONS, and TRACE methods are defined to be safe.

In my understanding, the following application violates the spec, because current-value is in the DB state of /objects-with-value/1 and changes with each call.

GET /objects-with-value/1
{
  "id": 1,
  "local-variables": {...}
  "current-value": 123.0
}

where

  • current-value depends on local-variables and also depends on the current day, and is the result of a call to an external service
  • current-value is persisted in the DB state of /objects-with-value/1

Question:

My assumption is that an application which does not violate the above mentioned RFC would rather look like this:

  • current-value is not in the DB state of /objects-with-value/1
  • instead, it is calculated on each GET call
  • the external call is cached

The assumption is only correct if the population of the cache is not considered a state change. Hence, the question: Is caching external calls considered a state change in the context of safe HTTP methods?

1
  • "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" It doesn't apply to your example. Because the change is not due to the call. Similarly if a file changes on the server side, the corresponding GET response will change. But not due to the request. It's not the request that changes the data. The data would change regardless. That's the point, and the difference with say POST.
    – freakish
    Commented Sep 12 at 7:04

2 Answers 2

6

The RFC clarifies this in the next few paragraphs:

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.

In other words, you can make state changes all you want on the server as long as it doesn't create any problems (or you as the host are willing to accept responsibility for those problems).

Another sentence that is relevant:

The purpose of distinguishing between safe and unsafe methods is to allow automated retrieval processes (spiders) and cache performance optimization (pre-fetching) to work without fear of causing harm.

For a safe method, whether you are caching in your server or some proxy layer between your server is caching your response shouldn't matter. It doesn't really make sense to say that it's OK e.g., for a client browser to cache a response from the server, but the server can't cache the data used to create the response.

Now, to be clear, it's not necessarily true that, in every particular case, caching is appropriate and won't result in issues. You need to consider the consequences of that. But it doesn't change whether your operation is safe.

0

Context matters.

For example, GET endpoints may be audited for who accesses what. The get logic may log some debug/trace messages along the way. A security token might get regenerated as part of the auth flow. Monitoring will register the incoming request and factor it into its graphs and stats.

All of these examples entail some kind of state change in some part of the system due to receiving a GET request, but they don't invalidate the general idea that a GET request does not change the application's state.

What the guideline indicates is that an API should not be designed in a way that a consumer has an expectation that state changes when they send a GET request. It focuses on the designed application behavior as far as the consumer is concerned; which is different from the private application implementation (which may contain secret operations or automations that don't necessarily play by the same rules).

Your Answer

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

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