Skip to content

Instantly share code, notes, and snippets.

@marija17
Created October 9, 2020 10:22
Show Gist options
  • Save marija17/550df5ca172f957a14a9cecf6c7b2888 to your computer and use it in GitHub Desktop.
Save marija17/550df5ca172f957a14a9cecf6c7b2888 to your computer and use it in GitHub Desktop.
import { GraphQLSchema, printSchema } from 'graphql';
import { transformSchemaFederation } from 'graphql-transform-federation';
import { makeSchema } from '@nexus/schema';
import graphqlTypeJson from 'graphql-type-json';
import { Products } from '../resolvers/Products';
import { Product } from '../resolvers/Product';
import { types } from '../core/product';
import { DirectiveNode, ObjectTypeDefinitionNode, parse, visit, print } from 'graphql/language';
export async function buildNexusFederatedSchema(
): Promise<GraphQLSchema> {
const schema = makeSchema({
types: [
graphqlTypeJson,
...types,
Product,
Products
],
outputs: {
schema: __dirname + '/generated/search.graphql',
typegen: __dirname + '/generated/search.ts'
}
});
const addFederationDirectives = transformSchemaFederation(schema, {
Query: {
extend: true,
},
Product: {
keyFields: ['id'],
},
BrandKeywordAggregationsOutput: {
keyFields: ['key'],
},
BrandTermAggregationBucket: {
keyFields: ['key'],
},
CategoryKeywordAggregationsOutput: {
keyFields: ['key'],
},
CategoryTermAggregationBucket: {
keyFields: ['key'],
}
});
// At this point our federation directives have been appropriatetly added to the schema
// Add a cache control directive
const ast = parse(printSchema(addFederationDirectives));
const addCachingDirectives = visit(ast, {
ObjectTypeDefinition: {
enter(node: ObjectTypeDefinitionNode) {
if (node.name.value === 'Product') {
const newDirective = createDirectiveNode('cacheControl', 'maxAge');
return {
...node,
directives: [...(node.directives || []), newDirective],
kind: node.kind,
};
}
return node;
}
}
});
console.log(print(addCachingDirectives))
// At this point the cache control directive is appropriately set for product but the federation directives are no longer there
return addCachingDirectives;
}
const createDirectiveNode = (
name: string,
argument: string
): DirectiveNode => {
return {
kind: 'Directive',
name: { kind: 'Name', value: name },
arguments: [{
kind: 'Argument',
name: { kind: 'Name', value: argument },
value: { kind: 'IntValue', value: '300' },
}],
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment