Navigation Menu

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 'toConfig' methods to all type system definitions objects #1331

Merged
merged 1 commit into from Jan 18, 2019

Conversation

IvanGoncharov
Copy link
Member

@IvanGoncharov IvanGoncharov commented May 1, 2018

I created this PR to get early feedback about toConfig feature so it's missing proper tests.

toConfig is intended to help with schema transformation by minimizing the amount of code you need write and maintain, e.g. recreateType from graphql-tools.
When I worked on graphql-voyager I created my own intermidiate format just to do schema transformations.

Moreover, toConfig will prevent bugs that occur when a new field is added. For example, lexicographicSortSchema doesn't respect newly added assumeValid and allowedLegacyNames fields.

description: ?string,
astNode?: ?ObjectTypeDefinitionNode,
extensionASTNodes: $ReadOnlyArray<ObjectTypeExtensionNode>,
|};
Copy link
Member Author

Choose a reason for hiding this comment

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

I can't use GraphQL*Config types since they have Thunk fields and a lot of fields marked as optional. Because without this new type all code that uses toConfig should have a lot of unnecessary runtime checks and also have dead code to handle Thunk.

Plus I think it easier to keep this types up to date than update extendSchema, lexicographicSortSchema, and all similar functions inside 3rd-party tools.

Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder whether we still need the Thunk fields in the GraphQL*Config types at all. This feels like a much cleaner expression of a GraphQL type without needing surrounding schema. I'll admit, I don't fully understand how the thunks are used currently, so take that idea as a relative newcomer's curiosity instead of a strong suggestion.

Copy link
Contributor

Choose a reason for hiding this comment

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

As far as I have always understood, the thunks are there to avoid circular references at module import time when your schema is made up of types each in their own module. We have definitely run into that situation a couple of times and switched to using thunks.

For toConfig, however, it’s indeed not necessary as by the time it can be invoked the import stage should already have passed.

Copy link
Contributor

@freiksenet freiksenet left a comment

Choose a reason for hiding this comment

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

This is amazing and super useful! Let's get it shipped! 👍 💯

Tests are needed here I guess.

@freiksenet
Copy link
Contributor

I've checked it against recreateType in graphql-tools and it looks like it matches what we have there, so it should be fine.

Copy link
Contributor

@mjmahone mjmahone left a comment

Choose a reason for hiding this comment

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

This is great! I have (internal to my repo) a few tools that are transforming the regular schema into an introspection schema and back, in order to do things like type trimming. Having this available would have made that code significantly cleaner!

I do want to make sure this doesn't end up in the public API in 14.0 though (I see you haven't modified any index.js, which is great): I still am not totally sure about the internal representation being best optimized for schema modification, and I think as a community we need to play around with it a bit to be sure. It would be annoying to have to cut a new major release just because we changed the GraphQL*ExactConfig API to get performance improvements, for example.

description: ?string,
astNode?: ?ObjectTypeDefinitionNode,
extensionASTNodes: $ReadOnlyArray<ObjectTypeExtensionNode>,
|};
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder whether we still need the Thunk fields in the GraphQL*Config types at all. This feels like a much cleaner expression of a GraphQL type without needing surrounding schema. I'll admit, I don't fully understand how the thunks are used currently, so take that idea as a relative newcomer's curiosity instead of a strong suggestion.

@@ -782,6 +853,16 @@ export type GraphQLObjectTypeConfig<TSource, TContext> = {
extensionASTNodes?: ?$ReadOnlyArray<ObjectTypeExtensionNode>,
};

export type GraphQLObjectTypeExactConfig<TSource, TContext> = {|
name: string,
interfaces: Array<GraphQLInterfaceType>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this instead be:

interfaces: Array<GraphQLInterfaceTypeExactConfig<TSource, TContext>>,

I'm not sure which makes sense: we definitely don't want to end up with a Schema where an object points to a different instance of the same interface vs. what the schema itself has. So we need to make sure, anywhere we hydrate a type out of this config, that it ends up pointing to the schema's actual interface type, rather than the interface type used at build time (I see you're already doing this everywhere it's used, but others might not be so prudent). I'd even be tempted to make this just Array<string> just to prevent any mismatches. At that point, we're basically be creating a stricter version of the Introspection schema (we seem to need a non-Introspection, but Introspection-like, representation regardless, so I'm still OK with this).

My worry may be a complete non-issue if we don't allow exporting these new types and limit how we use them within the repo.

@alloy
Copy link
Contributor

alloy commented Oct 25, 2018

@IvanGoncharov I’d love to have access to this 🙏 Currently I’ve copy-pasted some code from the extendSchema module into my own code https://github.com/artsy/metaphysics/pull/1346/files#diff-2092cb52bba31c5ad29eb09c6aa4c475R57.

I agree with the idea of not exporting this through the top-level index.js file yet, but other than that is there anything still blocking this?

@@ -674,6 +696,23 @@ export class GraphQLObjectType {
return this._interfaces;
}

toConfig(): {|
...GraphQLObjectTypeConfig<*, *>,
Copy link
Contributor

Choose a reason for hiding this comment

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

There's definitely another project for someone of figuring out how to get rid of all these * flow types (which are about as bad as any). Not this PR though.

Copy link
Contributor

@mjmahone mjmahone left a comment

Choose a reason for hiding this comment

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

This looks very good to me. It would be good to test the new toConfig function, but given we're already using it in other functions that are already well-tested, I'm not very concerned about it being wrong.

@@ -238,6 +238,27 @@ export class GraphQLSchema {
getDirective(name: string): ?GraphQLDirective {
return find(this.getDirectives(), directive => directive.name === name);
}

toConfig(): {|
...GraphQLSchemaConfig,
Copy link
Contributor

Choose a reason for hiding this comment

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

huh this must be new Flow wizardry: this is a nicely concise way of defining types in terms of other types!

Copy link
Contributor

@langpavel langpavel left a comment

Choose a reason for hiding this comment

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

Nice work!

@IvanGoncharov IvanGoncharov added this to the v14.2.0 milestone Jan 16, 2019
@IvanGoncharov IvanGoncharov added the PR: feature 🚀 requires increase of "minor" version number label Jan 17, 2019
@IvanGoncharov IvanGoncharov merged commit 92e647c into graphql:master Jan 18, 2019
@IvanGoncharov IvanGoncharov changed the title [RFC]Add 'toConfig' method Add 'toConfig' methods Jan 18, 2019
@IvanGoncharov IvanGoncharov deleted the toConfig branch January 20, 2019 02:03
martijnwalraven added a commit to apollographql/DefinitelyTyped that referenced this pull request Mar 6, 2019
@IvanGoncharov IvanGoncharov changed the title Add 'toConfig' methods Add 'toConfig' methods to all type system definitions objects Mar 26, 2019
rbuckton pushed a commit to DefinitelyTyped/DefinitelyTyped that referenced this pull request Mar 29, 2019
* Add Martijn Walraven  to "Definitions by" section of the package header

* Add `validateSDL` function

* Add `toConfig` methods

See graphql/graphql-js#1331

* Add missing typing for `print` function

See graphql/graphql-js#1702

* Rename `MaybePromise` to `PromiseOrValue`

graphql/graphql-js#1798

* Rename `blockStringValue.js` to `blockString.js`, and `blockStringValue` to `dedentBlockStringValue`

See graphql/graphql-js@16afd2e and graphql/graphql-js@60a2bf8

* Update `graphql` version to 14.2

* Add `.prettierrc` and reformat all files

This adds a `.prettierrc` based on the defaults used in #24552 (comment), and reformats all files (only a few are affected).

* Fix `GraphQLSchema.toConfig()`

* Remove `.prettierrc`
alesn pushed a commit to alesn/DefinitelyTyped that referenced this pull request Apr 23, 2019
* Add Martijn Walraven  to "Definitions by" section of the package header

* Add `validateSDL` function

* Add `toConfig` methods

See graphql/graphql-js#1331

* Add missing typing for `print` function

See graphql/graphql-js#1702

* Rename `MaybePromise` to `PromiseOrValue`

graphql/graphql-js#1798

* Rename `blockStringValue.js` to `blockString.js`, and `blockStringValue` to `dedentBlockStringValue`

See graphql/graphql-js@16afd2e and graphql/graphql-js@60a2bf8

* Update `graphql` version to 14.2

* Add `.prettierrc` and reformat all files

This adds a `.prettierrc` based on the defaults used in DefinitelyTyped#24552 (comment), and reformats all files (only a few are affected).

* Fix `GraphQLSchema.toConfig()`

* Remove `.prettierrc`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed PR: feature 🚀 requires increase of "minor" version number
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants