I'd like to create my schema with: https://www.apollographql.com/docs/engine/caching.html#hints-to-schema so it would be nice if I could define any arbitrary graphql directive to be passed to the compiled schema.
Maybe like:
@directive('@cacheControl(maxAge: 240)')
@ObjectType()
class MyClass {
...
}
Which should result in
type MyClass @cacheControl(maxAge: 240) {
...
}
AFAIK, graphql-js doesn't allow for easy registering server-side directives to schema.
There's extensionASTNodes field in ObjectType config but I need some research on this whether this is possible.
For things like caching and other stuff there is a middlewares feature with custom decorators support :wink:
Ok, I've done some research and looks like right now there's now way to register directives using graphql-js way:
Right now directives are purely a feature of the GraphQL language and IDL, so a schema not created using IDL definitionally won't contain directives. When building a schema in code, you have the full power of the host programming environment, so directives shouldn't be necessary. Directives are a tool for supplying additional intent to be later interpreted by the host programming environment.
However, it looks like there's a possibility to add an integration with Apollo Cache - apollo-cache-control sets cacheControl key on GraphQLResolveInfo:
https://github.com/apollographql/apollo-cache-control-js/blob/master/src/index.ts
So in this case you can create a middleware with custom decorator that will do the same job placing cache hints into GraphQLResolveInfo.
@19majkel94
I've made a middleware for apollo-cache-control after reading this post, but I still don't understand how it's supposed to work. I've set the maxAge to 60 seconds. The middleware seems to be working because I can see the cacheControl data in the extension field from the response.
But when I refresh the page within seconds, the resolver still queries the database. apollo-cache-control has no effects at all.
````
import {MiddlewareFn} from "type-graphql";
export function CacheControl(maxAge:number = 60): MiddlewareFn {
return ({info:{cacheControl}}, next) => {
cacheControl.setCacheHint({maxAge,scope:"PUBLIC"})
return next();
};
}
````
````
@Query(returnType => [Item])
@UseMiddleware(CacheControl())
public getItems() {
return dbGetData();
}
````
I haven't used apollo-cache-control yet, you should try this way in a simple example using graphql-js to see if this work at all and maybe open issue on apollo-cache-control-js repo:
https://github.com/apollographql/apollo-cache-control-js
Unfortunately, I have one's hands tied and I can't do anything until registering directives by code will be available in graphql-js:
https://github.com/graphql/graphql-js/issues/1343
I just read that apollo engine is required in order to work with cache control. I haven't set up apollo engine config in graphql yoga so I will try it later.
The caching finally works by adding Apollo Engine. https://github.com/graphcool/graphql-yoga/blob/master/examples/apollo-engine/index.js
````
const port = 3000;
const serverOptions: Options = {
port,
endpoint: "/graphql",
playground: "/playground",
tracing: true,
cacheControl: true
};
const engine = new ApolloEngine({
apiKey: process.env.APOLLO_ENGINE_KEY
});
const httpServer = graphQLServer.createHttpServer(serverOptions);
engine.listen(
{
port,
httpServer,
graphqlPaths: ['/graphql'],
},
() =>
console.log(
`Server with Apollo Engine is running on http://localhost:3000`,
),
)
````
Thanks for the research 馃槈 I am going to add integration with apollo-cache-control and apollo-engine to the examples section, along with custom @CacheControl decorator.
I really can't work out what the syntax would be for adding cache directives, are there any good examples of this yet?
edit - I read the whole bit from graphql-js and their reasons for not wanting to expose arbitrary directives, I get why this is hard now, I'm going to try implementing cache control through a middleware.
p.s. this library is great, thanks!
Most helpful comment
The caching finally works by adding Apollo Engine. https://github.com/graphcool/graphql-yoga/blob/master/examples/apollo-engine/index.js
````
const port = 3000;
````