-
-
Notifications
You must be signed in to change notification settings - Fork 7
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
Overhaul behavior system: no schema-time "smart defaulting" #349
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Previously the behavior system worked during the schema building process, inside the various schema hooks. So looking at the behavior of a `relation` might have looked like: ```ts GraphQLObjectType_fields_field(field, build, context) { const relation = context.scope.pgRelationOrWhatever; // Establish a default behavior, e.g. you might give it different default behavior // depending on if the remote table is in the same schema or not const defaultBehavior = someCondition(relation) ? "behavior_if_true" : "behavior_if_false"; // Now establish the user-specified behavior for the entity, inheriting from all the // relevant places. const behavior = getBehavior([ relation.remoteResource.codec.extensions, relation.remoteResource.extensions, relation.extensions ]); // Finally check this behavior string against `behavior_to_test`, being sure to apply // the "schema-time smart defaulting" that we established in `defaultBehavior` above. if (build.behavior.matches(behavior, "behavior_to_test", defaultBehavior)) { doTheThing(); } ``` This meant that each plugin might treat the behavior of the entity different - for example `postgraphile-plugin-connection-filter` might have a different `someCondition()` under which the "filter" behavior would apply by default, whereas the built in `condition` plugin might have a different one. Moreover, each place needs to know to call `getBehavior` with the same list of extension sources in the same order, otherwise subtle (or not so subtle) differences in the schema would occur. And finally, because each entity doesn't have an established behavior, you can't ask "what's the final behavior for this entity" because it's dynamic, depending on which plugin is viewing it. This update fixes all of this; now each entity has a single behavior that's established once. Each plugin can register `entityBehaviors` for the various behavior entity types (or global behaviors which apply to all entity types if that makes more sense). So the hook code equivalent to the above would now be more like: ```ts GraphQLObjectType_fields_field(field, build, context) { const relation = context.scope.pgRelationOrWhatever; // Do the thing if the relation has the given behavior. Simples. if (build.behavior.pgCodecRelationMatches(relation, "behavior_to_test")) { doTheThing(); } ``` This code is much more to the point, much easier for plugin authors to implement, and also a lot easier to debug since everything has a single established behavior now (except `refs`, which aren't really an entity in their own right, but a combination of entities...). These changes haven't changed any of the schemas in the test suite, but they may impact you. This could be a breaking change - so be sure to do a schema diff before/after this.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Previously the behavior system worked during the schema building process, inside the various schema hooks. So looking at the behavior of a
relation
might have looked like:This meant that each plugin might treat the behavior of the entity different - for example
postgraphile-plugin-connection-filter
might have a differentsomeCondition()
under which the "filter" behavior would apply by default, whereas the built incondition
plugin might have a different one.Moreover, each place needs to know to call
getBehavior
with the same list of extension sources in the same order, otherwise subtle (or not so subtle) differences in the schema would occur.And finally, because each entity doesn't have an established behavior, you can't ask "what's the final behavior for this entity" because it's dynamic, depending on which plugin is viewing it.
All of this was undesirable.
This PR changes things - now each entity has a single behavior that's established once. Each plugin can register
entityBehaviors
for the various behavior entity types (or global behaviors which apply to all entity types if that makes more sense). So the hook code equivalent to the above would now be more like:Much more to the point, much easier for plugin authors to implement, and also a lot easier to debug since everything has a single established behavior now (except
refs
, which aren't really an entity in their own right, but a combination of entities...).These changes haven't changed any of the schemas in the test suite, but they may impact you. This could be a breaking change - so be sure to do a schema diff before/after this.
Fixes #119