-
Notifications
You must be signed in to change notification settings - Fork 2k
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 buildASTSchemaComponents function #817
Conversation
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.
Makes a lot of sense! Thanks for this. Some small requests inline.
src/utilities/buildASTSchema.js
Outdated
*/ | ||
export function buildASTSchema(ast: DocumentNode): GraphQLSchema { | ||
export function buildASTSchemaConfig(ast: DocumentNode) { |
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 think we should define and specify a return type here (GraphQLSchemaConfig
, perhaps?).
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.
@wincent I can't return GraphQLSchemaConfig
since it require query
property to be not null:
type GraphQLSchemaConfig = {
query: GraphQLObjectType;
mutation?: ?GraphQLObjectType;
So it should some type identical to GraphQLSchemaConfig
but with query
defined as:
query: ?GraphQLObjectType;
Can you please suggest best way how to do this in Flow?
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.
Yeah, sorry: I didn't mean literally GraphQLSchemaConfig
; I meant some name like it.
In the worst case you define two types with different names. Better though, would be to use an intersection type:
type Base = {
mutation?: ?GraphQLObjectType;
subscription?: ?GraphQLObjectType;
types?: ?Array<GraphQLNamedType>;
directives?: ?Array<GraphQLDirective>;
};
type A = Base & {
query: GraphQLObjectType;
};
type B = Base & {
query?: GraphQLObjectType;
};
(Leaving the actual names of A
and B
out just for illustration.)
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.
@wincent Thank you. I used "GraphQLSchemaComponents" as the name for the new type and also rename function to buildASTSchemaComponents
.
src/utilities/buildASTSchema.js
Outdated
* has no resolve methods, so execution will use default resolvers. | ||
*/ | ||
export function buildASTSchema(ast: DocumentNode): GraphQLSchema { | ||
const config:any = buildASTSchemaConfig(ast); |
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.
nit: if we were to keep this any
(and I don't think we should), we'd want a space after the colon.
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.
@wincent I added space. As for using proper type it's the same problem with typing that I described in my previous comment :(
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.
@wincent I tried to make config: GraphQLSchemaComponents
but it sims that Flow don't recognize runtime checks like this one: https://github.com/graphql/graphql-js/pull/817/files#diff-2691b670eb7e51187edc1f918c624a70R145
So when I call new GraphQLSchema(config)
flow produce an error saying query
is missing. Can you please advice on how to make this possible in Flow?
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.
@wincent I think it last change suggested in your review. Can you please advice how it can be solved in Flow?
src/utilities/buildASTSchema.js
Outdated
@@ -132,10 +132,9 @@ function getNamedTypeNode(typeNode: TypeNode): NamedTypeNode { | |||
* If no schema definition is provided, then it will look for types named Query | |||
* and Mutation. | |||
* | |||
* Given that AST it constructs a GraphQLSchema. The resulting schema | |||
* has no resolve methods, so execution will use default resolvers. | |||
* Given that AST it return object that can be used to construct GraphQLSchema. |
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.
spelling: return → returns
suggest: "construct GraphQLSchema" → "construct a GraphQLSchema instance"
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.
👍 Fixed
97fa9f0
to
5eb11f0
Compare
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'm curious - if you only expect to parse types and directives and explicitly working around not wanting to provide a schema
definition, why also parse the schema
definition in this new function?
Also, this is also including the standard built-in types in the return, is that what you need from this function? It's a bit strange that built-in types are added but built-in directives are not.
I also think the naming of this new function is confusing. Is the intent that you would use the response of it to call new GraphQLSchema()
? It doesn't sound like it from the PR description. Maybe buildASTDefinitions
?
I don't think you need this new function to be called directly by buildASTSchema
. I'm sure they can share a majority of implementation via module-private functions, but this particular implementation seems to cripple the intent described at the top of the PR.
src/utilities/buildASTSchema.js
Outdated
* Given that AST it constructs a GraphQLSchema. The resulting schema | ||
* has no resolve methods, so execution will use default resolvers. | ||
*/ | ||
export function buildASTSchema(ast: DocumentNode): GraphQLSchema { |
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 should be the first function in the file since its eponymous.
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.
Thanks, done.
src/utilities/buildASTSchema.js
Outdated
* has no resolve methods, so execution will use default resolvers. | ||
*/ | ||
export function buildASTSchema(ast: DocumentNode): GraphQLSchema { | ||
const config: any = buildASTSchemaComponents(ast); |
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.
Shouldn't need an :any
cast here, at least not without clear comment as to why. Seems unsound
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.
@leebyron I tried to make config: GraphQLSchemaComponents
but it seems that Flow doesn't recognize runtime checks like this one: https://github.com/graphql/graphql-js/pull/817/files#diff-2691b670eb7e51187edc1f918c624a70R145
So when I call new GraphQLSchema(config)
, Flow produces an error saying query is missing
. Could you please advice on how to make this possible in Flow?
5eb11f0
to
ad9c2aa
Compare
@leebyron In PR description I only described the main problem we try to address with this PR. At the same time, sometimes we need to inject type or directive into schema build from user-supplied IDL. Currently, we use string concatenation and I tried to address both problems in a single function but I'm happy to split it into
No, it doesn't include standard built-in types. Please see this test-case: https://github.com/graphql/graphql-js/pull/817/files#diff-59b5c9e589eeac323b0666278abb95e9R47 |
ad9c2aa
to
089ee42
Compare
089ee42
to
2ad7595
Compare
@@ -127,6 +130,43 @@ function getNamedTypeNode(typeNode: TypeNode): NamedTypeNode { | |||
* has no resolve methods, so execution will use default resolvers. | |||
*/ | |||
export function buildASTSchema(ast: DocumentNode): GraphQLSchema { | |||
const config: any = buildASTSchemaComponents(ast); |
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 believe you can fix the any check with:
const config = buildASTSchemaComponents(ast);
if (!config.query) {
throw new GraphQLError(
'Must provide schema definition with query type or a type named Query.',
ast,
);
}
...
return new GraphQLSchema(config);
I believe the issue for flow is that config.query
can be undefined
in addition to null
.
Closing since now we can create schemas without root type. |
At the moment you can use IDL only to describe entire Schema.
But in a few our projects we need to build only directives and associated types from IDL.
We work around this by appending following to the IDL:
This PR splits out the major part of
buildASTSchema
function code and allows to get types and directives before they are passed toGraphQLSchema
constructor.