Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mergeSchemas with string typedefs drops schema directives #862

Closed
terion-name opened this issue Jun 24, 2018 · 15 comments
Closed

mergeSchemas with string typedefs drops schema directives #862

terion-name opened this issue Jun 24, 2018 · 15 comments
Labels
blocking Prevents production or dev due to perf, bug, build error, etc..

Comments

@terion-name
Copy link

terion-name commented Jun 24, 2018

I've faced problem, that my schema directives don't work at all. There are numerous issues about directives in tracker, maybe they all are related to this

I have multiple modular schemas that are merged.

For example a schema:

directive @auth(scopes: [String]) on FIELD | FIELD_DEFINITION

type TypeTranslated implements Node {
    id: ID!
    createdAt: DateTime!
    updatedAt: DateTime!
    color: String! @auth(scopes: ["foo"])
    title: String!
    documents: [Document!]!
}

And another:

directive @relation(service: String!, type: String!, batch: String!, key: String = "id") on FIELD_DEFINITION

type Document implements Node {
    id: ID!
    responsible: ID! @relation(service: "cc-structure", type: "Unit", batch: "units(where: {id_in: $ids})")
}

Directive resolvers are:

import { GraphQLEnumValue, GraphQLField } from 'graphql';
import { SchemaDirectiveVisitor } from 'graphql-tools';

export default class RelationDirective extends SchemaDirectiveVisitor {
  constructor(config: any) {
    console.log(config);
    super(config);
  }

  visitFieldDefinition(field: GraphQLField<any, any>) {
    const {service, type, batch, key} = this.args;
    console.log(JSON.stringify({relation: {
        service, type, batch, key: key || 'id'
      }}));
    field.description = JSON.stringify({relation: {
        service, type, batch, key: key || 'id'
      }});
  }
}
import {SchemaDirectiveVisitor} from "graphql-tools";
import {GraphQLField, GraphQLObjectType} from "graphql";
import {guard} from "../../server";

export default class AuthDirective extends SchemaDirectiveVisitor {
  visitObject(object: GraphQLObjectType) {
    const fields = object.getFields();
    for (let field in fields) {
      const f: GraphQLField = fields[field];
      f.resolve = guard(f.resolve, this.args.scopes);
    }
    return object;
  }

  // remove field if not authentificated
  visitFieldDefinition(field: GraphQLField) {
    console.log(field.resolve);
    field.resolve = guard(field.resolve, this.args.scopes, ()=>null);
    return field;
  }
}

And nothing is fired.

After long digging I've found the following:

    // schemas - array of parsed schemas
    console.log(schemas.map(s => s._directives)); // here I see in console my auth and relation directives
    this._schemaCache = mergeSchemas({schemas: [...schemas, ...this._overrides], schemaDirectives: {
        auth: AuthDirective,
        relation: RelationDirective,
      }});
    console.log(this._schemaCache._directives); // and here they are gone and only default ones left

Had no luck to make this work, a huge stopper :(

UPD

I've used this to test and run it at different points of execution:

SchemaDirectiveVisitor.visitSchemaDirectives(schema, {
        relation: class extends SchemaDirectiveVisitor {
          visitFieldDefinition(field: GraphQLField<any, any>) {
            console.log(field);
          }
        }
      });

Running it over this._schemaCache from example above results in console.log calls.

BUT!

I further need to collect several merged and processed schemas and to merge them again:

    let schemas = builders.map(b => b.buildSchema());
    let overrides = [].concat(...builders.map(b => b.getOverrides())).filter(v => !!v);
    const merged = mergeSchemas({schemas: [...schemas, ...overrides], schemaDirectives: {
        auth: authDirective.default,
        relation: relationDirective.default,
      }});

And running above visitor over merged results in nothing.

But there is an important thing: overrides contains string typedefs — I use them to resolve some merging conflicts with graphql-import. If I remove them — visitor works. So the problem is in merging schema with string typedefs

@ghost ghost added the blocking Prevents production or dev due to perf, bug, build error, etc.. label Jun 24, 2018
@terion-name terion-name changed the title mergeSchemas drops schema directives mergeSchemas with string typedefs drops schema directives Jun 24, 2018
@ghost ghost added the blocking Prevents production or dev due to perf, bug, build error, etc.. label Jun 24, 2018
@snrbrnjna
Copy link

I'm not sure, if mergeSchema makes use of schema introspection, because as stated here, directives aren't transferrable to a remoteProxy 👎

Perhaps that's the reason why your Directives get lost, when merging schemas.

@januszhou
Copy link

I'm having a similar issue now, any updates?

@snrbrnjna
Copy link

@freiksenet do you have any comments on this?

@helipilot50
Copy link

helipilot50 commented Jan 30, 2019

I have the same issue. We have numerous schema modules that are merged using mergeSchemas(). The combined schema does not contain any custom directives.

@freiksenet
Copy link
Contributor

freiksenet commented Jan 30, 2019 via email

@andrew-makarenko
Copy link

any news? It's blocking for me as well

@tlivings
Copy link
Contributor

Waiting for news as well.

@yaacovCR
Copy link
Collaborator

yaacovCR commented May 1, 2019

Looks like #1003 was merged one month ago.

It should be available via the 5.0.0 alpha tag

https://github.com/apollographql/graphql-tools/blob/master/CHANGELOG.md

@herenickname
Copy link

Tried to install all used Apollo modules to the next tag. Nothing happened.

@lastmjs
Copy link

lastmjs commented Jul 3, 2019

I switched to this project for now: https://github.com/Urigo/merge-graphql-schemas

@yaacovCR
Copy link
Collaborator

yaacovCR commented Jul 3, 2019

You might also try graphql-tools-fork.

@sajsanghvi
Copy link

Any luck on this?

@yaacovCR
Copy link
Collaborator

Does it work in the fork? https://npmcharts.com/compare/graphql-tools-fork

@hsehweil
Copy link

hsehweil commented Jan 2, 2020

@yaacovCR
Copy link
Collaborator

yaacovCR commented Apr 1, 2020

Fixed in latest stable release, set mergeDirectives to true.

@yaacovCR yaacovCR closed this as completed Apr 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocking Prevents production or dev due to perf, bug, build error, etc..
Projects
None yet
Development

No branches or pull requests