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

Re-add dynamic validation by request #2232

Conversation

stevefan1999-personal
Copy link

@stevefan1999-personal stevefan1999-personal commented Jan 27, 2019

This patch re-mimic the behavior of the same functionality in graphql-yoga, so that validation rules that relies on query context (e.g. variables for slicknode/graphql-query-complexity & pa-bru/graphql-cost-analysis) can work again without ugly workarounds.

Related: slicknode/graphql-query-complexity#7, pa-bru/graphql-cost-analysis#12, #1777

TODO:

  • Update CHANGELOG.md with your change (include reference to issue & this PR)
  • Rebase your changes on master so that they can be merged easily
  • Make sure all tests and linter rules pass

@apollo-cla
Copy link

@stevefan1999-personal: Thank you for submitting a pull request! Before we can merge it, you'll need to sign the Meteor Contributor Agreement here: https://contribute.meteor.com/

@martijnwalraven
Copy link
Contributor

Thanks for opening a PR for this, but I don't think making validation depend on request context is the right approach. Validation rules are meant to rely on the query document and schema only, and not on variables or other request-specific information.

One of the reasons for that is that according to the GraphQL spec, validation is a phase that can be skipped when the operation has been validated before. We've recently implemented a document cache for this, and we've seen significant performance improvements as a result (this work is part of 2.4.0).

What is your use case for this? In most cases, a plugin implementing didResolveOperation and performing checks there is a better solution.

@stevefan1999-personal
Copy link
Author

@martijnwalraven I've show some example plugins that worked before the great apollo-server refactor. They *need* those request variables to perform a proper DFS, or they still works but crippled, because they had limited information to scope on the fields selected. Besides, I don't think validation should be immutable either.
Also, speaking of the ugly workarounds, this is one of them.

@martijnwalraven
Copy link
Contributor

@stevefan1999-personal Yeah, I realize those plugins worked before, but I'm afraid that is not what validation is meant for. Validation rules not depending on request context is part of the GraphQL spec, and breaking that would limit our ability to optimize performance.

If you need to perform per-request checks that depend on variables or other request context, the didResolveOperation hook in the Apollo Server plugin API should be a good alternative (see #2008 for more details on this).

@P4sca1
Copy link

P4sca1 commented May 7, 2019

@martijnwalraven When using plugins, we dont have access to the validationContext which is needed to get schema / types via validationContext.getSchema().getType(). Is there any way to do this in a plugin?

@glasser
Copy link
Member

glasser commented Oct 4, 2022

As Martijn described above, the validation phase intentionally is designed to be very cacheable and not depend on anything other than the schema and operation text.

The didResolveOperation plugin hook runs at an appropriate time to do more detailed validation and if it throws a GraphQLError, that error will be send to the client (we should perhaps update the comments and docs to state that that's a reliable part of the plugin API rather than a coincidence).

@glasser glasser closed this Oct 4, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants