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

Nullability/error awareness improvements #3438

Open
swizzlr opened this issue Sep 9, 2024 · 5 comments
Open

Nullability/error awareness improvements #3438

swizzlr opened this issue Sep 9, 2024 · 5 comments
Labels
codegen Issues related to or arising from code generation feature New addition or enhancement to existing solutions

Comments

@swizzlr
Copy link

swizzlr commented Sep 9, 2024

Use case

I would like to have a similar feature set to Apollo Kotlin which is adopting semanticNonNull in order to more accurately describe the domain of null because nothing, null because of error, and null because of bubbled error. I would also like the solution to provide ergonomic access to field errors for existing nullable types

Describe the solution you'd like

  • Improved accessors. One or a choice of the following (the choice could be configured through codegen or directive parameters):
    • for a semantically non-null field:
      • var field: String { get throws(GraphQLError) } or
      • var field: Result<String, GraphQLError> or
      • @SemanticNonNull var field: String? where @SemanticNonNull is a property wrapper providing a projected value $field that is of type GraphQLError?
    • for a semantically nullable field:
      • the above accessors, except with optionals where appropriate
  • A way to opt-in to this behavior incrementally via schema directives. For consistency's sake, the Kotlin implementation seems like a sensible starting point: https://www.apollographql.com/docs/kotlin/advanced/nullability#introduction.

Given the spec is still in flux, dropping the server directive and simply offering something like _semanticNonNullField might be a good way to scare off uninitiated users who aren't following the workgroup discussions.

I understand Swift 6 is a big priority right now but at least having this on the roadmap would be a good start, I think!

@swizzlr swizzlr added the feature New addition or enhancement to existing solutions label Sep 9, 2024
@swizzlr
Copy link
Author

swizzlr commented Sep 9, 2024

Or perhaps

@SemanticNonNull var field: String? where @SemanticNonNull is a property wrapper providing a projected value $field that is of type Result<String?, GraphQLError

@calvincestari
Copy link
Member

HI Thomas, thanks for creating the issue.

I understand Swift 6 is a big priority right now but at least having this on the roadmap would be a good start, I think!

Yes you're correct Swift 6 is the big priority, but has been on my mind to get something experimental into Apollo iOS that we can test and learn from to inform the direction of the proposals. I agree that getting visibility on the roadmap of our intention is a good idea. Client Controlled Nullability used to be available but was removed once it was determined the proposal wasn't going to advance.

Given the spec is still in flux, dropping the server directive and simply offering something like _semanticNonNullField might be a good way to scare off uninitiated users who aren't following the workgroup discussions.

All of this still has a reliance on a server implementation though because it needs to understand that sending null is possible/supported for a field instead of bubbling up and potentially blowing out the entire operation.

@swizzlr
Copy link
Author

swizzlr commented Sep 9, 2024

All of this still has a reliance on a server implementation though because it needs to understand that sending null is possible/supported for a field instead of bubbling up and potentially blowing out the entire operation.

Oh, I must be mistaken/not explaining myself correctly.

What I'm requesting here is that a server-defined nullable field can be declared by the client to be semantically non null, and therefore when the server returns a null in that field Apollo should make it easy for me to grab the error, if any, and type it in swift as a non-optional type. Obviously if the field is null and there is no field error then it's a programming error on my part. My understanding is that that server behavior is already part of the standard (returning nulls and using the errors array).

@calvincestari
Copy link
Member

calvincestari commented Sep 10, 2024

Thanks for clarifying, I better understand what you're asking for now.

What I'm requesting here is that a server-defined nullable field can be declared by the client to be semantically non null, and therefore when the server returns a null in that field Apollo should make it easy for me to grab the error, if any, and type it in swift as a non-optional type.

When I first read this I read it as just a simpler way to access the field error, instead of having to search through the field errors array and find the matching path, etc. Yes - this would be a nice improvement. Changing the type to non-optional I'm not so sure on, but I do like the throwing getter suggestion; that should work since we use DataDict as the backing store and don't actually have to store a non-optional value.

Obviously if the field is null and there is no field error then it's a programming error on my part. My understanding is that that server behavior is already part of the standard (returning nulls and using the errors array).

I'm not certain we can rely on this assumption though because I'm not 100% sure on the field error behaviour of nullable fields. The GraphQL spec makes specific mention of non-null types but nothing that states a field error must be raised for nullable types. I think you can infer that a field error should be raised but nothing to state that it must be. It would be good to clarify that behaviour with the working group.

@calvincestari calvincestari added the codegen Issues related to or arising from code generation label Sep 10, 2024
@calvincestari
Copy link
Member

calvincestari commented Sep 10, 2024

Obviously if the field is null and there is no field error then it's a programming error on my part. My understanding is that that server behavior is already part of the standard (returning nulls and using the errors array).

I'm not certain we can rely on this assumption though because I'm not 100% sure on the field error behaviour of nullable fields. The GraphQL spec makes specific mention of non-null types but nothing that states a field error must be raised for nullable types. I think you can infer that a field error should be raised but nothing to state that it must be. It would be good to clarify that behaviour with the working group.

I've read and re-read this section of the spec countless times and while the language could be clearer I believe we're to assume that a field error is required in the "errors" list regardless of the type. I think that's going to be the common understanding of when a field error must be raised.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
codegen Issues related to or arising from code generation feature New addition or enhancement to existing solutions
Projects
None yet
Development

No branches or pull requests

2 participants