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

Query variables validation #227

Merged
merged 53 commits into from
Dec 15, 2021
Merged

Query variables validation #227

merged 53 commits into from
Dec 15, 2021

Conversation

cecton
Copy link
Contributor

@cecton cecton commented Dec 1, 2021

Changes

  • Remove unneeded Option around Request's variables`: this has been moved to Remove unneeded option #257 (review this first to reduce the diff size here 🧠)
  • Add error variant ValidationInvalidTypeVariable for variables of invalid type
  • Introduce new module spec for our higher level representation of GraphQL's Schema and Query: this has been moved to Cleanup prelude and create spec module #258 (review this first to reduce the diff size here 🧠)
  • Clean-up prelude and added a note: this has been moved to Cleanup prelude and create spec module #258 (review this first to reduce the diff size here 🧠)
  • Removed schema parameter from Query's constructor: if the schema changes we don't want the query to be executed on a wrong
    schema. So unless we include the Schema to the hashing (Hash) we should make this a parameter of the methods of Query.
  • Introduce public method validate_variables on Query that allows type validation of the request's variable (the whole point of the damn PR, see Variable types are not validated #62)
  • Add a lot of transformation from apollo-rs's ast to our own (private) higher level representation API: FieldType, ObjectType, Interface, ...
  • Refactor fragments creation to its own type so it can be re-used in the Schema and Query
  • Refactor formatting tests so we don't need to update everything when our API changes
  • Add a bunch of type validation tests
  • Made Schema's is_subtype() private: we don't need to expose that to the user (at least not for now...)
  • Parse and validate the query before making a query plan
  • Fix invalid integration tests for missing variables: we used to check for the variables to be present before running the query plan. The implementation was not correct as the variables are optional by default unless the type is a non-null type. I removed this entirely in favor of this new variable type validation.
  • Fix a tracing stuff according to ADR on telemetry.
  • Add documentation
  • Disable parse error printing if log level is OFF

Fixes #62

@cecton cecton self-assigned this Dec 1, 2021
@cecton
Copy link
Contributor Author

cecton commented Dec 2, 2021

Waiting on #233 before continuing

@cecton cecton force-pushed the cecton-query-variable-validation branch from ec094f5 to d5f8d25 Compare December 2, 2021 16:11
@cecton cecton force-pushed the cecton-query-variable-validation branch from e6186ff to 6a6602e Compare December 4, 2021 09:39
@o0Ignition0o
Copy link
Contributor

I’ll see myself out 😂🤣

@Geal
Copy link
Contributor

Geal commented Dec 14, 2021

ok so I worried more about what is said in

Removed schema parameter from Query's constructor: if the schema changes we don't want the query to be executed on a wrong schema. So unless we include the Schema to the hashing (Hash) we should make this a parameter of the methods of Query.

than about what the code is actually doing, which does not change much. A big assumption in the way we execute query is that the schema will not change during the query: if we establish a query plan from a query and schema, when formatting at the end it should still be the same schema. This is the benefit that was given by carrying the schema along with the query, it guarantees that the same schema will be used for the entire life of the query, even if the calling code in apollo-router changes.

Now looking more at the code, this is mainly affecting the query cache, that caches the query parsed with apollo-rs and does not require the schema, than the CachingQueryPlanner who needs both query and schema. So it's ok. Maybe I just worry too much 😅

@o0Ignition0o
Copy link
Contributor

this is mainly affecting the query cache, that caches the query parsed with apollo-rs and does not require the schema, than the CachingQueryPlanner who needs both query and schema.

This is the key point imo

@Geal
Copy link
Contributor

Geal commented Dec 14, 2021

Perf test please

@cecton
Copy link
Contributor Author

cecton commented Dec 14, 2021

Perf test please

We now have automatic perf tests! ^_^ https://github.com/apollographql/router/pull/227/checks?check_run_id=4517674898

@abernix
Copy link
Member

abernix commented Dec 14, 2021

We now have automatic perf tests! ^_^ https://github.com/apollographql/router/pull/227/checks?check_run_id=4517674898

@cecton From what I understand, they only get triggered and show up there if you explicitly request them using the phrasing above (or some variations, like Je voudrais un test de perf 😉 ). So they are semi-automated.

@cecton
Copy link
Contributor Author

cecton commented Dec 14, 2021

This is the key point imo

To me the key point is more like: there is a way to use the API where you can instantiate the query with a one schema and do validation/formatting with another 😅 I don't need to look at the cache to know that it is wrong. Pretty sure it was done by me and completely unintentionally.

@cecton
Copy link
Contributor Author

cecton commented Dec 14, 2021

@cecton From what I understand, they only get triggered and show up there if you explicitly request them using the phrasing above (or some variations, like Je voudrais un test de perf wink ). So they are semi-automated.

Oh nice! There was one available before though:

@cecton
Copy link
Contributor Author

cecton commented Dec 14, 2021

Oh my branch makes huge perf improvement 😂 that's probably not right lol

@cecton
Copy link
Contributor Author

cecton commented Dec 14, 2021

Perf test please

@Geal
Copy link
Contributor

Geal commented Dec 14, 2021

Oh my branch makes huge perf improvement 😂 that's probably not right lol

It looks like it compares to one of my failed attempts in the mutex PR 🤭

@cecton
Copy link
Contributor Author

cecton commented Dec 15, 2021

OH NOW WE HAVE SCORES!!

Mine: 7287
main: 7195

Wait... this is still wrong XD this PR should be slower....

Copy link
Contributor

@BrynCooke BrynCooke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor issues around validation logic, but otherwise looks good.

) -> Result<(), InvalidValue> {
match (self, value) {
(FieldType::String, Value::String(_)) => Ok(()),
(FieldType::Int, Value::Number(number)) if number.is_i64() || number.is_u64() => Ok(()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integers need to be a signed 32 bit integer https://spec.graphql.org/June2018/#sec-Int

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh god really

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 91d51fb

}

impl FieldType {
pub(crate) fn validate_value(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Float, Integer and Bool can be represented as strings, so coercion supported need to be added. Can be a followup ticket though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what, where did you see that? oh that would explain what i saw with the ID type

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 41e2279

Copy link
Contributor

@garypen garypen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know what you think about the question I have on FieldTypes. Apart from that, looks good!

apollo-router-core/src/query_cache.rs Outdated Show resolved Hide resolved
// should always serialize as a String."
//
// In practice it seems Int works too
(FieldType::Id, Value::String(_) | Value::Number(_)) => Ok(()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this indicate a problem somewhere. In other words, if it should serialize as a String, why are we getting Numbers?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No I think it's the type coercion mentioned by Bryn there: #227 (comment)

@garypen
Copy link
Contributor

garypen commented Dec 15, 2021

OH NOW WE HAVE SCORES!!

Mine: 7287 main: 7195

Wait... this is still wrong XD this PR should be slower....

I think there is "variation" in the benchmarking system due to "noisy neighbours" in the cloud and other source of variance.

@cecton
Copy link
Contributor Author

cecton commented Dec 15, 2021

I think there is "variation" in the benchmarking system due to "noisy neighbours" in the cloud and other source of variance.

Ah I restarted it and now I have 6912... which seems to low

@Geal
Copy link
Contributor

Geal commented Dec 15, 2021

Ah I restarted it and now I have 6912... which seems to low

no need to worry too much for a 5% difference. Panic when it's larger than 20% 😄

@cecton cecton merged commit 2e627f3 into main Dec 15, 2021
@cecton cecton deleted the cecton-query-variable-validation branch December 15, 2021 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Variable types are not validated
6 participants