A Nexus plugin integrating Apollo Federation 2.0
yarn add @korzun/nexus-federation-plugin
or
npm i @korzun/nexus-federation-plugin
Note you must also add nexus
. The plugin pins to it as a peer dependency.
import { plugin as federationPlugin } from '@korzun/nexus-federation-plugin';
import { makeSchema, objectType } from 'nexus';
// Create example User Type
const User = objectType({
name: 'User',
keys: ['id'],
definition(t) {
t.id('id');
t.string('name');
},
});
// Build Nexus Schema
const schema = makeSchema({
types: [User],
plugins: [
federationPlugin(),
]
});
import { ApolloServer, gql } from 'apollo-server-core';
import { buildSubgraphSchema } from '@apollo/subgraph';
import { getResolversFromSchema } from '@graphql-tools/utils';
// Create Subgraph Schema from Nexus Schema
const resolvers = getResolversFromSchema(nexusSchema);
const typeDefs = gql.(printSchema(nexusSchema));
//@ts-expect-error buildSubgraphSchema doesn't recognize the IResolvers type
const subgraphSchema = buildSubgraphSchema({ typeDefs, resolvers });
// Start Apollo Server
const server = new GraphQLServer({ schema })
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
objectType({
name: 'User',
definition: (t) => {
t.string('email', { external: true });
t.string.field('review', { type: 'Review' });
},
});
objectType({
name: 'User',
keys: ['id'],
definition(t) {
t.id('id');
t.string('name');
},
});
objectType({
name: 'User',
keyFields: ['id'],
definition: (t) => {
t.id('id');
t.nullable.string('name', override: 'SubgraphA');
},
});
objectType({
name: 'Review',
keyFields: ['id'],
definition: (t) => {
t.field('product', { type: 'Product', provides: ['name'] });
},
});
objectType({
name: 'User',
keyFields: ['id'],
definition: (t) => {
t.id('id', { external: true });
t.nullable.string('email', { external: true });
t.list.field('reviews', { type: 'Review', requires: ['email'] });
},
});
objectType({
name: 'Product',
keyFields: ['upc'],
definition: (t) =>
{
t.field('upc', { type: 'UPC' }); // shareable, upc is a key field
t.string('name'); // non-shareable
t.string('description', { shareable: true }); // shareable
}
});
objectType({
name: 'User',
shareable: true,
definition: (t) => {
t.string('name'); // shareable, User is marked shareable
t.string('email'); // shareable, User is marked shareable
},
});