-
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
Update Optional field to be not required #82
base: main
Are you sure you want to change the base?
Conversation
If a field is Optional, generated code shouldn't mark it as required like Field(..., alias="some_alias"). This change will allow dynamic graphql response with directives to pass validation. Signed-off-by: Di Wang <[email protected]>
Please don't merge this PR. It's on purpose to have optional fields as required. The main purpose of the GQL classes is the validation of the schemas in our code. We want to know if a schemas change breaks our code. So we have to specify all attributes, including optionals, in case of breaking changes, mypy will notice it. For our tests, we've introduced |
@chassing This is blocking app-sre/qontract-reconcile#3470, we need optional field to be not required to pass validation, otherwise typed query will fail to dynamic response (with |
I don't know the |
It works similar to our template get_aws_account, but in server side, we always pass the same gql body, but with different query variables, graphql server will generate different response. |
For this change, you need approval from @fishi0x01; as I said, he implemented it on purpose. I could imagine a special |
This is not a blocker anymore because |
This is a very interesting topic indeed. Here are my main thoughts around this. 1. Type ambiguity with UnionsThe main reason we enforce Optionals to be set is to achieve a strict data <-> schema mapping in order to be sure
Inline fragments are interpreted as Lets take the following as an example: query C($flag: Boolean!) {
data {
x
... on B {
y
}
... on D {
y
z @include(if: $flag) {
sth
}
}
... on E {
somethingelse
}
}
} If we say that However, one might argue that a query like the above doesn't really make much sense, is very constructed and unlikely to happen. Still, this made me worry and Im not sure if there are more cases where that might be a potential issue - so back then the decision was done to strictly match the data structure with the data to be on the safe side. 2. @include with NonNull fieldsIf we decide to make Optionals not required, then my understanding is that there is still a problem with query JenkinsConfigs($flag: Boolean!) {
jenkins_configs: jenkins_configs_v1 {
name
...on JenkinsConfig_v1 {
instance @include(if: $flag) {
name
}
type
}
}
} This will yield: class JenkinsConfigV1_JenkinsConfigV1(JenkinsConfigV1):
instance: JenkinsInstanceV1 = Field(..., alias="instance")
q_type: str = Field(..., alias="type") I.e., even if we make Optionals not required, then any 3. Why do we need @include?My understanding is that Personally, I think it would be better to have queries dedicated for a specific set of data in order ConclusionAll that being said, qenerate should not enforce any style and ideally fully comply with the gql standard. In order to do so, Wdyt? |
By following GraphQL spec, if a field has no value, but it's defined in query, it should be kept in response (no directive case). So always make optional field required is OK, as optional is derived from GraphQL spec, not really a normal optional as we usually use. Some JSON serializer may have options to ignore empty values, but to comply with GraphQL spec, it shouldn't be used. Directives may makes things dynamic, so it's hard to define a complete static typing in this case, may worth explore how it's done in other languages, how to they support this feature? |
If a field is Optional, generated code shouldn't mark it as required like
Field(..., alias="some_alias")
, doc.This change will allow dynamic graphql response with directives to pass validation.