-
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
More allowed legacy names #1235
Changes from 7 commits
5cb3dd9
5f9ff08
3958eae
8f936da
bb9c68c
3beb355
50be8c6
e58be0f
ae1ab1d
e8b6262
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1225,18 +1225,23 @@ describe('extendSchema', () => { | |
query: new GraphQLObjectType({ | ||
name: 'Query', | ||
fields: () => ({ | ||
id: { type: GraphQLID }, | ||
__badName: { type: GraphQLString }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you add a new test rather than changing this existing one? |
||
}), | ||
}), | ||
allowedLegacyNames: ['__badName'], | ||
}); | ||
const ast = parse(` | ||
extend type Query { | ||
__badName: String | ||
__anotherBadName: String | ||
} | ||
`); | ||
const schema = extendSchema(testSchemaWithLegacyNames, ast); | ||
expect(schema.__allowedLegacyNames).to.deep.equal(['__badName']); | ||
const schema = extendSchema(testSchemaWithLegacyNames, ast, { | ||
allowedLegacyNames: ['__anotherBadName'], | ||
}); | ||
expect(schema.__allowedLegacyNames).to.deep.equal([ | ||
'__badName', | ||
'__anotherBadName', | ||
]); | ||
}); | ||
|
||
describe('does not allow extending a non-object type', () => { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -60,15 +60,10 @@ import type { | |
IntrospectionNamedTypeRef, | ||
} from './introspectionQuery'; | ||
|
||
import type { GraphQLSchemaValidationOptions } from '../type/schema'; | ||
|
||
type Options = {| | ||
/** | ||
* When building a schema from a GraphQL service's introspection result, it | ||
* might be safe to assume the schema is valid. Set to true to assume the | ||
* produced schema is valid. | ||
* | ||
* Default: false | ||
*/ | ||
assumeValid?: boolean, | ||
...GraphQLSchemaValidationOptions, | ||
|}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still think it's better to have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gotcha, makes sense 👍 |
||
|
||
/** | ||
|
@@ -414,5 +409,6 @@ export function buildClientSchema( | |
types, | ||
directives, | ||
assumeValid: options && options.assumeValid, | ||
allowedLegacyNames: options && options.allowedLegacyNames, | ||
}); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,8 @@ import { ASTDefinitionBuilder } from './buildASTSchema'; | |
import { GraphQLError } from '../error/GraphQLError'; | ||
import { isSchema, GraphQLSchema } from '../type/schema'; | ||
|
||
import type { GraphQLSchemaValidationOptions } from '../type/schema'; | ||
|
||
import { | ||
isObjectType, | ||
isInterfaceType, | ||
|
@@ -38,14 +40,7 @@ import type { | |
} from '../language/ast'; | ||
|
||
type Options = {| | ||
/** | ||
* When extending a schema with a known valid extension, it might be safe to | ||
* assume the schema is valid. Set to true to assume the produced schema | ||
* is valid. | ||
* | ||
* Default: false | ||
*/ | ||
assumeValid?: boolean, | ||
...GraphQLSchemaValidationOptions, | ||
|
||
/** | ||
* Descriptions are defined as preceding string literals, however an older | ||
|
@@ -245,6 +240,14 @@ export function extendSchema( | |
types.push(definitionBuilder.buildType(typeName)); | ||
}); | ||
|
||
// Support both original legacy names and extended legacy names. | ||
const schemaAllowedLegacyNames = schema.__allowedLegacyNames; | ||
const extendAllowedLegacyNames = options && options.allowedLegacyNames; | ||
const allowedLegacyNames = | ||
schemaAllowedLegacyNames && extendAllowedLegacyNames | ||
? schemaAllowedLegacyNames.concat(extendAllowedLegacyNames) | ||
: schemaAllowedLegacyNames || extendAllowedLegacyNames; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice 👍 |
||
|
||
// Then produce and return a Schema with these types. | ||
return new GraphQLSchema({ | ||
query: queryType, | ||
|
@@ -253,8 +256,7 @@ export function extendSchema( | |
types, | ||
directives: getMergedDirectives(), | ||
astNode: schema.astNode, | ||
allowedLegacyNames: | ||
schema.__allowedLegacyNames && schema.__allowedLegacyNames.slice(), | ||
allowedLegacyNames, | ||
}); | ||
|
||
function appendExtensionToTypeExtensions( | ||
|
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.
The
assumeValid
configuration is about whether or not to check the configuration for common mistakes, so regardless of that the allowed legacy names still need to be stored on the schema instance.There’s no tests for
assumeValid
and the below configuration being set or not, so wasn’t sure what you’d like. Should I add a test for any configuration being set, regardless ofassumeValid
?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.
Adding a test would be great!
Let me know if I understand this correctly - you could create a GraphQLSchema with both
__allowedLegacyNames
andassumeValid
, then extend that schema with a legacy name (which might no longer be assumed invalid), and then expect validation to pass?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.
Hmm, I now see that
validate
depends on the private__validationErrors
property of a schema instance.I’m now starting to think that maybe what Relay is doing isn’t entirely correct. First it creates a schema with
assumeValid
set, then after extending that schema a few times it expects to still be able to validate that schema, which appears to only really be possible becauseextendSchema
does not copy over theassumeValid
configuration.Maybe
extendSchema
should also copy over theassumeValid
setting, butvalidate
could accept an optional parameter to force performing the validations regardless of__validationErrors
already being set?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.
Not quite. extendSchema produces a new schema - while the provided schema may have been "valid" (either assumed or validated), the returned schema is different and may be invalid, so it must not copy over assumeValid or __validationErrors from the input. We would expect the extended schema to be validated by validateSchema().
Now, we may want to provide a similar assumeValid option for extendSchema, but that would be a separate thing.
validate checks __validationErrors first as a form of memoization. Since schema are considered immutable, we do not want to wastefully validate the same schema multiple times.
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.
Relay first builds a schema with the assumeValid set, because it expects that schema has been provided from a valid GraphQL server - whereas any client side extensions are within Relay's responsibility to validate
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.
Also, the
GraphQLValidator
second link is validating the graphql operations and fragments found within relay product code, not the schemaThere 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.
Ok, I see, that makes sense. So to answer your initial question, when an original schema has
__allowedLegacyNames
then extending that schema should still allow those original legacy names too, regardless from whether or not they were validated on the original schema.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.
That
validate
call inGraphQLValidator
is definitely still leading to an error about the legacy name in the schema . Maybe it’s just a side-effect, though, I’ll double-check that in the morrow.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.
Probably a side effect - the document validator first asserts that a valid schema if being used to validate a document. If the schema wasn't validated before that point, it will throw