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
Conversation
src/type/definition.js
Outdated
description: ?string, | ||
astNode?: ?ObjectTypeDefinitionNode, | ||
extensionASTNodes: $ReadOnlyArray<ObjectTypeExtensionNode>, | ||
|}; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
I've checked it against |
There was a problem hiding this 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.
src/type/definition.js
Outdated
description: ?string, | ||
astNode?: ?ObjectTypeDefinitionNode, | ||
extensionASTNodes: $ReadOnlyArray<ObjectTypeExtensionNode>, | ||
|}; |
There was a problem hiding this comment.
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.
src/type/definition.js
Outdated
@@ -782,6 +853,16 @@ export type GraphQLObjectTypeConfig<TSource, TContext> = { | |||
extensionASTNodes?: ?$ReadOnlyArray<ObjectTypeExtensionNode>, | |||
}; | |||
|
|||
export type GraphQLObjectTypeExactConfig<TSource, TContext> = {| | |||
name: string, | |||
interfaces: Array<GraphQLInterfaceType>, |
There was a problem hiding this comment.
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.
@IvanGoncharov I’d love to have access to this 🙏 Currently I’ve copy-pasted some code from the I agree with the idea of not exporting this through the top-level |
c27a2f4
to
b318257
Compare
b318257
to
c8d1c28
Compare
@@ -674,6 +696,23 @@ export class GraphQLObjectType { | |||
return this._interfaces; | |||
} | |||
|
|||
toConfig(): {| | |||
...GraphQLObjectTypeConfig<*, *>, |
There was a problem hiding this comment.
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.
There was a problem hiding this 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, |
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work!
* 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`
* 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`
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 fromgraphql-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 addedassumeValid
andallowedLegacyNames
fields.