Skip to content
This repository was archived by the owner on Sep 3, 2021. It is now read-only.
This repository was archived by the owner on Sep 3, 2021. It is now read-only.

makeAugmentedSchema with isFederated:true breaks @search directive and searchSchema function #594

Open
@MeetSnowmaker

Description

@MeetSnowmaker

Hello there,

I tried to implement the new @search directive on a federated microservice.

[nodemon] starting `babel-node services/graph_canvas_service/src/index.js`
[nodemon] spawning
[nodemon] child pid: 21404
augmentedSchema
(node:18004) UnhandledPromiseRejectionWarning: TypeError: schema.getTypeMap is not a function
    at mapSearchDirectives (C:\projects\someLearning\backend\services\graph_canvas_service\node_modules\neo4j-graphql-js\dist\schemaSearch.js:72:33)
    at schemaSearch (C:\projects\someLearning\backend\services\graph_canvas_service\node_modules\neo4j-graphql-js\dist\schemaSearch.js:43:30)
    at _callee$ (C:\projects\someLearning\backend\services\graph_canvas_service\node_modules\neo4j-graphql-js\dist\index.js:541:62)    at tryCatch (C:\projects\someLearning\backend\services\graph_canvas_service\node_modules\regenerator-runtime\runtime.js:63:40)
    at Generator.invoke [as _invoke] (C:\projects\someLearning\backend\services\graph_canvas_service\node_modules\regenerator-runtime\runtime.js:293:22)
    at Generator.next (C:\projects\someLearning\backend\services\graph_canvas_service\node_modules\regenerator-runtime\runtime.js:118:21)
    at asyncGeneratorStep (C:\projects\someLearning\backend\services\graph_canvas_service\node_modules\@babel\runtime-corejs2\helpers\asyncToGenerator.js:5:24)
    at _next (C:\projects\someLearning\backend\services\graph_canvas_service\node_modules\@babel\runtime-corejs2\helpers\asyncToGenerator.js:27:9)
    at C:\projects\someLearning\backend\services\graph_canvas_service\node_modules\@babel\runtime-corejs2\helpers\asyncToGenerator.js:34:7
    at new Promise (<anonymous>)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:18004) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:18004) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are
not handled will terminate the Node.js process with a non-zero exit code.
[nodemon] clean exit - waiting for changes before restart

After a few hours I started to reduce the configuration line by line. It appears when the functions restructures the schema to be @apollo/federation compatible some functions being 'lost in translation'.

Sample code with some debugging rampage:
to reproduce the error uncomment the line
// isFederated: true,

import '@babel/polyfill/noConflict';

import {
  // neo4jgraphql,
  makeAugmentedSchema,
  searchSchema,
  // augmentSchema,
  // cypher,
} from 'neo4j-graphql-js';
import neo4j from 'neo4j-driver';

import { ApolloServer, gql } from 'apollo-server';
import { buildFederatedSchema } from '@apollo/federation';
import fs from 'fs';

import Mutation from './resolvers/Mutation';
import { Query } from './resolvers/Query';

const generateApolloService = async () => {
  const driver = neo4j.driver(
    process.env.NEO4J_URI || 'bolt://localhost:7687',
    neo4j.auth.basic(
      process.env.NEO4J_USER || 'neo4j',
      process.env.NEO4J_PASSWORD || 'letmein',
    ),
  );

  const typeDefs = gql(
    fs.readFileSync(__dirname.concat('/schema.graphql'), 'utf8'),
  );

  const resolvers = {
    Mutation,
    // Query,
  };

  const schema = await makeAugmentedSchema({
    // typeDefs: typeDefs,
    typeDefs: `
   
    type Movie {
      title: String @search
      year: Int
      imdbRating: Float
      genres: [Genre] @relation(name: "IN_GENRE", direction: OUT)
  }
  type Genre {
      name: String
      movies: [Movie] @relation(name: "IN_GENRE", direction: IN)
  }
    `,
    // resolvers: resolvers,
    config: {
      experimental: true,
      // isFederated: true,
      query: true,
      mutation: true,
      debug: true,
    },
  });

  console.log('augmentedSchema');

  const wtf = await searchSchema({ schema, driver, debug: true });

  console.log('wtf', wtf);

  const apolloMicroService = new ApolloServer({
    schema: buildFederatedSchema([schema]),
    // dataSources: () => ({
    //   withdrawalAPI: new WithdrawalAPI(),
    // }),
    context: ({ req }) => {
      return {
        driver: driver,
        // claims: req.headers?.claims ? JSON.parse(req.headers.claims) || null,
      };
    },
    debug: true,
    tracing: true,
  });

  return apolloMicroService;
};

export { generateApolloService as default };

After removing isFederated from config it runs as expected

[searchSchema] Search indexes dropped using Cypher:
  CALL db.indexes() YIELD name, provider WHERE provider = "fulltext-1.0"
  CALL db.index.fulltext.drop(name)
  RETURN TRUE

[searchSchema] Search indexes created using Cypher:
  CALL db.index.fulltext.createNodeIndex("MovieSearch",["Movie"],["title"])
  RETURN TRUE

I guess I could manually call the drop and create Cypher queries on init for now.
Only the searchSchema({ schema, driver, debug: true }); breaks the schema and resolvers are generated and working as expected.

Keep up the good work 🚀

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions