Apollo-link-rest: Query Nested Rest Cache Redirects

Created on 12 Mar 2019  路  11Comments  路  Source: apollographql/apollo-link-rest

Hi,

Is it possible to use apollo cache for nested rest calls in a query?

For example, given the following query, would it be possible to retrieve author from cache (if available) instead of actually fetching the data?

query library { books @rest(type: "Book", path: "/books") { title year authorId @export(as: "authorID") author @rest(type: "Author", path: "/authors/{exportVariables.id}") { firstname lastname } } }

I've tried to configure cacheRedirects in apollo's InMemoryCache but it never seemed to work.

help wanted 馃洜

Most helpful comment

I think there's potential in adding id and cache parameters to @rest personally. The user could basically tell A-L-R "My purpose in calling this REST request is to retrieve the Post with id="foo"; if you already have it in the cache skip the request and return it directly". A-L-R could then pretty easily run a query on the cache for that resource before making the request.

It would add a pretty significant feature to the library, though, so I'd leave it up to the maintainers to decide whether it's worth looking into.

All 11 comments

Can you create a minimal example demonstrating the issue? AFAIK the cache would be before the rest link in the chain, so it should be getting stored in the same way as a regular query.

I'll try to publish an example ASAP. Caching does work indeed but just on the top level (e.g. for books in my example) but not on nested rest annotated objects

@NikoSperat We have a PR looking to improve @export( support, so if you could contribute a unit-test we'd be able to validate that your use-case is covered!

See here: https://github.com/apollographql/apollo-link-rest/pull/204

I don't think my PR will address this, it only deals with the correctness of @export variables. Seems like this issue relates more to doing a cache check before fetching a nested @rest request.

It seems like pulling this data from cache would require some user intervention to me. Apollo won't necessarily know that the user at /authors/{exportVariables.id} will be an Author with id=id. As a developer, you're aware of this, so you could provide that intelligence, but it seems difficult for the library to anticipate any use cases to provide default behaviors.

Perhaps a custom fetch function which integrates with the cache would achieve what you want.

I suppose an id param could be added to the @rest directive which, combined with type, could do a cache check for you. But I would also worry about hidden behaviors like that; some users (myself included) wouldn't expect @rest to be cached by default and would prefer that a nested fetch update the resource even if it is cached. Not necessarily a bad feature to add though, if it's configurable and the use case is clearly defined.

It is as @a-type explained. Now I see the issues here, why it would be difficult to respond with cached data.
I actually wrote a short PoC with a custom fetch function and direct cache lookup. Wasn't too difficult, but in the end this will just add some more custom code that is hard to maintain. - Thats what we tried to avoid and why we are using apollo and link-rest instead of writing our own fetching libraries in the first place.
Giving the possiblity to provide a custom redirect function for nested rest objects and resolving these beforehand would probably be a good solution

I think there's potential in adding id and cache parameters to @rest personally. The user could basically tell A-L-R "My purpose in calling this REST request is to retrieve the Post with id="foo"; if you already have it in the cache skip the request and return it directly". A-L-R could then pretty easily run a query on the cache for that resource before making the request.

It would add a pretty significant feature to the library, though, so I'd leave it up to the maintainers to decide whether it's worth looking into.

Is there a way to achieve this with custom code in the meantime? I'm trying to do this exact thing and any hints would be greatly appreciated

@typon In theory, you could possibly use readFragment within a custom fetch function using some logic you write to determine the intent of the request by the URL provided. If the readFragment returns data for the resource, you could repackage it to look like a normal fetch response and return it instead of making the request. But I'm sure there would be other pitfalls to work around when writing that.

I don't have anything to add to this thread, as shown in a-type's comments, it would be a pretty significant change, and I don't exactly know how to make this feature work in a globally-efficient & easy to maintain way. It's possible聽@typon @NikoSperat should consider apollo-link-state (now directly a part of apollo client) as a way to achieve your needed API.

You're definitely looking at the internals of Apollo, however!

If it were me, I would split this into two queries that get the job done sequentially.

@fbartho is this the same for non-nested @rest queries? For example, in the example below, will warehouses be resolved from the cache when Book query is called after Books query? I was quite sure it will, but it's not. Am I missing something?

query Books
  books @rest(type: "[Book]", path: "/books") {
    id
    sku
  }
  warehouses @rest(type: "[Warehouse]", path: "/warehouses") {
    id
    name
  }
}
query Book
  book @rest(type: "Book", path: "/books/123") {
    id
    sku
  }
  warehouses @rest(type: "[Warehouse]", path: "/warehouses") {
    id
    name
  }
}

Detailed control of caching is more of a question for ApolloClient. (And some of it might not be easy to do with apollo-links)

Additionally, I鈥檓 pretty sure with pure GraphQL it also wouldn鈥檛 resolve those two types of queries directly from the cache, and would hit your backend twice there too.

GraphQL does not really understand that the book-by-id query is exactly equivalent to find-entry-in-books-list-query-that-matches-my-id. Does that make sense @edgars-sirokovs ?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

i-Hun picture i-Hun  路  4Comments

Simply007 picture Simply007  路  5Comments

timhwang21 picture timhwang21  路  7Comments

MichelDiz picture MichelDiz  路  7Comments

Paddy-Hamilton picture Paddy-Hamilton  路  7Comments