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

Add inheritResolversFromInterfaces option #720

Merged
merged 4 commits into from
Apr 10, 2018

Conversation

reconbot
Copy link
Contributor

@reconbot reconbot commented Apr 6, 2018

This adds inheritResolversFromInterfaces to addResolveFunctionsToSchema and makeExecutableSchema

Later on we'll want to support interfaces implementing other interfaces
graphql/graphql-spec#295

TODO:

  • If this PR is a new feature, reference an issue where a consensus about the design was reached Types should inherit from interfaces when applying resolver map #616
  • Make sure all of the significant new logic is covered by tests
  • Rebase your changes on master so that they can be merged easily
  • Make sure all tests and linter rules pass
  • Update CHANGELOG.md with your change. Include a description of your change, link to PR (always) and issue (if applicable). Add your CHANGELOG entry under vNEXT. Do not create a new version number for your change yourself.

@ghost ghost added the feature New addition or enhancement to existing solutions label Apr 6, 2018
@reconbot reconbot force-pushed the interface-resolver-inheritance branch from bf9e1af to 3e01db4 Compare April 6, 2018 20:17
@ghost ghost added the feature New addition or enhancement to existing solutions label Apr 6, 2018
@reconbot reconbot force-pushed the interface-resolver-inheritance branch from 3e01db4 to 0b1931f Compare April 6, 2018 20:20
@reconbot reconbot changed the title Add inheritResolversFromInterfaces option Add inheritResolversFromInterfaces option Apr 6, 2018
@ghost ghost added the feature New addition or enhancement to existing solutions label Apr 6, 2018
@reconbot
Copy link
Contributor Author

reconbot commented Apr 9, 2018

cc @benjamn =)

Copy link
Contributor

@benjamn benjamn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good so far! Just a few suggestions regarding options parameter style.

resolverValidationOptions: IResolverValidationOptions = {},
inheritResolversFromInterfaces: boolean = false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than adding another boolean positional argument, let's merge the validation options and the resolver inheritance option into a single options parameter. This will probably require a more general name for the IResolverValidationOptions type, such as IAddResolveFunctionsToSchemaOptions.

More on why boolean positional arguments are problematic: https://ariya.io/2011/08/hall-of-api-shame-boolean-trap

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely agree but I was avoiding making a breaking change to the public api. I'll see about supporting call signatures with a warning as discussed on twitter.

@@ -69,6 +69,7 @@ function _generateSchema(
allowUndefinedInResolve: boolean,
resolverValidationOptions: IResolverValidationOptions,
parseOptions: GraphQLParseOptions,
inheritResolversFromInterfaces: boolean
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This boolean argument is fine because _generateSchema is private to this module (and not exported like addResolveFunctionsToSchema).

const typeNames = new Set([
...Object.keys(schema.getTypeMap()),
...Object.keys(resolvers)
]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little simpler?

const typeNames = Object.keys({
  ...schema.getTypeMap(),
  ...resolvers,
});

Having an array rather than a Set should be fine because the only usage below is calling forEach.

return;
}

const interfaceResolvers = (type as GraphQLObjectType).getInterfaces().map((iFace) => resolvers[iFace.name]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might be able to reorganize this code so that the type.getInterfaces() call is inside a type instanceof GraphQLObject conditional block, so you don't have to explicitly cast it. Then you could put the code above in the else branch and avoid the early return, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I love returning early!

But I also see what you mean and this is a much cleaner suggestion.

Copy link
Contributor Author

@reconbot reconbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated with a new interface

resolverValidationOptions: IResolverValidationOptions = {},
inheritResolversFromInterfaces: boolean = false
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely agree but I was avoiding making a breaking change to the public api. I'll see about supporting call signatures with a warning as discussed on twitter.

return;
}

const interfaceResolvers = (type as GraphQLObjectType).getInterfaces().map((iFace) => resolvers[iFace.name]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I love returning early!

But I also see what you mean and this is a much cleaner suggestion.

@reconbot
Copy link
Contributor Author

reconbot commented Apr 10, 2018

(working on docs but welcome a review on the changes)

@reconbot
Copy link
Contributor Author

reconbot commented Apr 10, 2018

Added some docs about the new api and rebased

This adds `inheritResolversFromInterfaces` to `addResolveFunctionsToSchema` and `makeExecutableSchema`

Later on we'll want to support interfaces implementing other interfaces
graphql/graphql-spec#295
@reconbot reconbot force-pushed the interface-resolver-inheritance branch from 8906bed to 302e1a6 Compare April 10, 2018 15:57
schema: options,
resolvers: legacyInputResolvers,
resolverValidationOptions: legacyInputValidationOptions
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@benjamn benjamn merged commit c470ffc into ardatan:master Apr 10, 2018
@reconbot reconbot deleted the interface-resolver-inheritance branch April 10, 2018 18:53
@reconbot
Copy link
Contributor Author

🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New addition or enhancement to existing solutions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants