neo4j / graphql

A GraphQL to Cypher query execution layer for Neo4j and JavaScript GraphQL implementations.
https://neo4j.com/docs/graphql-manual/current/
Apache License 2.0
507 stars 149 forks source link

Support for federation #202

Closed SolarLiner closed 3 years ago

SolarLiner commented 3 years ago

Is your feature request related to a problem? Please describe. neo4j-graphql-js had support for Apollo Federation to build a subgraph, this version has a regression in that regard.

Describe alternatives you've considered It's impossible to use alternatives besides staying on the old version, as this generates the schema internally instead of exposing generated resolvers.

darrellwarde commented 3 years ago

Hey @SolarLiner, while it sounds like we maybe need to expose our resolvers, `@graphql-tools/utils exposes a function getResolversFromSchema which you may be able to use to get our resolvers. Give it a go and let me know if it works?

darrellwarde commented 3 years ago

Rough example of something which might work:

const { getResolversFromSchema } = require("@graphql-tools/utils");
const { mergeTypeDefs } = require("@graphql-tools/merge");
const { makeExecutableSchema } = require("@graphql-tools/schema");
const { Neo4jGraphQL } = require("@neo4j/graphql");
const { printSchema } = require("graphql");

const neoSchema = new Neo4jGraphQL({
  typeDefs,
  driver,
});

const someService = new ApolloServer({
  schema: buildFederatedSchema([
    {
      typeDefs: printSchema(neoSchema.schema),
      resolvers: getResolversFromSchema(neoSchema.schema),
    },
  ]),
  context: ({ req }) => {
    return {
      driver,
      req,
    };
  },
});
darrellwarde commented 3 years ago

(You may need to wrap printSchema(neoSchema.schema) with gql() for it work)

SolarLiner commented 3 years ago

Being fairly new with GraphQL I had not even thought of looking into graphql-tools. This seems to be promising, thank you!

SolarLiner commented 3 years ago

Hi, for posterity, I have found an alternative method with graphql-transform-federation which allows adding federation-related directives to the schema that the Neo4jGraphQL generator does not know about. Simply generate the schema as you would, and transform the schema as you're passing it to the ApolloServer configuration, like this:

  // Create ApolloServer instance that will serve GraphQL schema created above
  // Inject Neo4j driver instance into the context object, which will be passed
  //  into each (autogenerated) resolver
  const neoServer = new ApolloServer({
    context: ({ req }) => ({ req, driver }),
    schema: transformSchemaFederation(neoSchema.schema, {
      Query: { extend: true },
      User: {
        extend: true, keyFields: ["userId"], fields: {
          userId: { external: true },
        }
      }
    }),
    introspection: true,
  });

This seems to work quite well. Thanks anyways for the initial idea,as it made me stumble into this alternative workaround.

process0 commented 3 years ago

Note, this only works if you do not extend any typedefs.

matola commented 2 years ago

Has there been any movement on this (support for neo4j graphQL endpoints as a subgraph)? I see a couple of pretty stale projects that attempt to help? The example above doesn't work as you would need to include the federation schema fragment in the neo4j schema, but then the buildSubgraph complains that they are already defined.