1

This question/answer from another user was very informative as to what idempotent means:

What is an idempotent operation?

When it comes to Rest API, since caching for GET requests can quickly be enabled if not already, if a user is wanting to fetch some examples: /users/:id or /posts/:id, they can do so as many times as they'd like and it shouldn't mutate any data.

If I'm understanding correctly, a GET request is idempotent in this case.

QUESTION

I believe Relay and Dataloader can help with GraphQL queries as far as caching, but doesn't address browser/mobile caching.

  • If we're talking about just the GET request portion of GraphQL, it's part of a single endpoint, what could I use tech/features or otherwise, that would address the benefits that regular http requests provide caching-wise.
mph85
  • 1,276
  • 4
  • 19
  • 39
  • 1
    Please limit your questions to one per post. There's already several questions concerning caching strategies with GraphQL, like [this one](https://stackoverflow.com/questions/41553360/does-graphql-has-the-same-caching-ability-as-rest). Additionally, asking for examples of use cases of GraphQL vs REST is pretty broad and likely to elicit opinionated answers. Maybe this question could be distilled to simply something like "What GraphQL requests, if any are considered idempotent?" – Daniel Rearden Jun 25 '19 at 02:25
  • @DanielRearden appreciate the feedback, has been revised, please take a look. – mph85 Jun 25 '19 at 04:27

1 Answers1

3

Idempotence vs Caching

First of all, caching and idempotence are different things and do not necessarily relate to one another. Caching may or may not be used to implement idempotent operations - it is certainly not a requirement.

Secondly, when speaking of HTTP requests, idempotence essentially concerns the state of the server rather than its responses. An idempotent operation will have leave the server in the exact same state if performed multiple times. It does not mean that the responses returned by an idempotent operation will be the same (although they often might be).

GET requests in REST are expected to be idempotent by contract - i.e. a GET operation must not have any state-altering side-effects on the server (technically this may not always be true, but for the sake of the explanation let's assume it is). This does not mean that if you GET the same resource multiple times, you'll always get the same data back. Actually, that wouldn't make sense since resources change over time and may be deleted as well right? So caching GET responses can help with performance but has nothing to do with idempotence.

Another way to look at it is that you are querying for a resource rather than arbitrary data. A GET request is idempotent in that you'll always get the same resource and you won't modify the state of the system in any way.

Finally, a poorly (oddly?) developed GET operation on the server side might have side-effects, which would violate the REST contract and make the operation non idempotent. Simple response caching would not help in such a case.

GraphQL

I like to see GraphQL queries as equivalent to GETs in REST. This means that if you query for data in GraphQL, the resolvers must not perform any side-effects. This would ensure that performing the same query multiple times will leave the server in an unchanged state.

Just like in a simple GET you'd be querying for specific resources, although unlike in GET, GraphQL allows you to query for many instances of many different types of resources at once. Once again, that does not mean identical responses, first and foremost because the resources may change over time.

If some of your queries have side-effects (i.e. they alter the state of the resources on the server), they are not idempotent! You should probably use mutations instead of queries to achieve these side-effects. Using mutations would make it clear to the client/consumer that the operation is not idempotent and should be treated accordingly (mutation inputs may accept idempotence keys to ensure Stripe-like idempotency, but that's a separate topic).

Caching GraphQL responses

I hope that by now it's clear that caching is not required to ensure / is not what determines the idempotency of GraphQL queries. It's only used to improve performance.

If you are still interested in server-side caching options for GraphQL, there are plenty of resources. You could start by reading what Apollo Server documentation has to say on the topic. Don't forget that you can also cache database/service/etc. responses. I am not going provide any specific suggestions since, judging by your question, there's much grater confusion elsewhere.

Avius
  • 5,504
  • 5
  • 20
  • 42