Type-graphql: Apollo's schema hints (apollo cache integration)

Created on 7 May 2018  路  8Comments  路  Source: MichalLytek/type-graphql

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) {
  ...
}
Question Solved

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;

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`,
        ),
)

````

All 8 comments

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!

Was this page helpful?
0 / 5 - 0 ratings