Now we have an official REST datasource with cache enabled, while maybe I missed it in the doc but I am wondering how to do server-side cache for a graphQL datasource (like prisma)?
Theoretically it would be just the same logic with the caching strategy on apollo-client: we get some data from a graphql query, normalize it into a memory/redis cache, (and for what the client-side does't have, we should config expiration time for them); when dealing with another query, just check the cache first (the logic has been already done in apollo-client).
So any recommended way to do this on the server-side? Is it possible to add a new data access layer between a graphql datasource (prisma) and our apollo-server (prisma <-> [an apollo-client like cache layer] <-> apollo-server) ?
Just need clarifying before commenting:
Or is it more like:
In most cases it would be the latter: just like how we call rest datasources -- we can our own application-level graphql API and then in its resolvers we call another graphql datasource to get the data.
The scenario for schema stitching is relatively rare, coz even when we need to simply forward a query to prisma, we always need to do some aithentication check or query complexity check before the forwarding. (I am not sure if I understand schema stitching/proxy right. Maybe we can also do such checks for schema stitching.)
If that's the case, then technically a GraphQL request would be the same as a RESTful HTTP request, I believe. That would allow you to utilize the REST datasource/caching, as long as a few things line up.
You would need to consider a few things:
A GraphQL request is similar to a database request, where you typically optimize the fields returned,
depending on the original query. Currently, the main point of the REST datasource cache is to cache an entire resource, since you can't typically optimize the fields anyway. Then, since the full resource is cached, multiple user requests could utilize that cached resource.
Typically you would optimize the fields or request shape for a database or GraphQL query, depending on the original request. A naive example could be that you over-request the fields/resources for the first GraphQL request, to get a large response similar to a typical RESTful query. You may be able to use the HTTP cache for the rest datasource without modification, but it may be better to combine some logic into a new cache connector method (they are pretty simple in design)
To continue the naive example, you would treat the returned graphql data as basic json, similar to the RESTful data. You would need to normalize the JSON into resources & types to increase cache hits,
There are a few strategies and tools to make everything easier, this is just a starter note.
I would just setup a test and try it out, to see how the http-cache handles the request, it's pretty automatic out of the box, just serializing the url for the endpoint, then storing the data in a key/value pair. You can fork the http-cache package and hack on it, to not use the url, but instead a combination of type names/resources. If you use the redis cache package, you inspect the cache data easier, as it comes in. I typically use Medis.
You would need to normalize the JSON into resources & types to increase cache hits,
Apollo-client is just doing nearly the same thing: sending graphql requests, normalizing the returned JSON into __typename:id key-value cache. Is it feasible to just use apollo-client with a redis cache to achieve this on the server-side?
I'm also interested in a nice solution to this, except I'm using schema delegation via graphql-tools. @beeplin, I think your use case may be a little bit different as it sounds like you're also using graphql-client on your server. Is that the case?
+1 for server-side caching
+1
Thanks for submitting this @beeplin. For now, this isn't something we're interested in implementing or maintaining, but it's certainly something that can be implemented outside of Apollo Server (and worthwhile!).
Most helpful comment
+1 for server-side caching