Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GraphQL_nullability__state_of_the_union.pdf

mbonnin
December 14, 2023
20

 GraphQL_nullability__state_of_the_union.pdf

mbonnin

December 14, 2023
Tweet

Transcript

  1. { "data" { "video": { "id": "42", "title": "GraphQL 101",

    "uploadDate": "2023-12-03T22:26:46Z" } } }
  2. Error null != Semantic null { "errors": [ { "message":

    "cannot resolve title", "path": "video.title" } ] "data": { "video": { "id": "42", "title": null } } }
  3. Terminology • Error null ◦ Exceptional case ◦ Has an

    error in the errors array • Semantic null ◦ Business case ◦ No error in the errors array
  4. Post mortem • New feature: video upload • During the

    upload, a video doesn’t have a title yet • This was a backward compatible schema change!
  5. @Composable fun VideoItem(response: Response) { if (response.errors.isNotEmpty()) { Error() }

    else { if (response.data.video.title == null) { Text(text = "This video doesn't have a title yet") } else { Text(text = response.data.video.title) } } }
  6. @Composable fun VideoItem(response: Response) { if (response.errors.any { it.path ==

    "video.title" }) { Error() // Can't display a video without a title } else { if (response.data.video.title != null) { Text(text = "This video does not have a title yet") } else { Text(text = response.data.video.title!!) } if (response.errors.any { it.path == "video.viewCount" }) { // Skip viewCount } else { Text(text = "${response.data.video.viewCount!!} + views") } } } Partial data
  7. GraphQL is missing types Your favorite type-safe language GraphQL string

    → String! string | null → String string | error → String string | null | error → String
  8. Documentation type Video { """ The title of the Video

    null if the video has just been uploaded """ title: String """ Number of times this video has been watched Never null unless there is an error """ viewCount: Int }
  9. Nullability working group 2021 Client Controlled Nullability May 2023 sub

    working group Sep 2023 GraphQL conf True nullability Asterisk Interrobang Oct 2023 semantic-non-null @strictNullability @catch graphql/nullability-wg
  10. Nullability working group 2021 Client Controlled Nullability May 2023 sub

    working group Sep 2023 GraphQL conf True nullability Asterisk Interrobang Oct 2023 semantic-non-null @strictNullability @catch graphql/nullability-wg
  11. Asterisk string → String! string | null → don’t use

    string | error → String* string | null | error → String graphql/graphql-spec/pull/1048 Never a semantic null
  12. Strict nullability string → String! string | null → don’t

    use string | error → String string | null | error → String? graphql/graphql-wg/discussions/1410 schema @strictNullability { query: Query } Never a semantic null
  13. Conclusion • null is not always what it seems! •

    be aware of the tradeoffs • document nullability • get involved!
  14. Input nullability string → String! string | null → String

    string | absent → String string | null | absent → String graphql/graphql-spec/issues/476
  15. Semantic non-null string → String! string | null → don’t

    use string | error → !String string | null | error → String graphql/graphql-spec/pull/1065
  16. Interrobang string → String! string | null → don’t use

    string | error → String!? string | null | error → String graphql/graphql-spec/pull/1046
  17. string → String! string | null → don’t use string

    | error → String @semanticNonNull string | null | error → String @semanticNonNull
  18. Problem 2: what default? • Fail the whole query ◦

    Easy ◦ Fragile • Handle field errors ◦ Hard ◦ Robust
  19. Opting in error handling • Start easy • Add error

    handling progressively fragment VideoDetails on Video { video { title # opt-in error handling viewCount @catch } } facebook/relay/issues/4416
  20. Opting in error handling fragment VideoDetails on Video { video

    { title # opt-in error handling viewCount @catch } } sealed interface Result<T> { class Success(val value: T): Result class Failure(val error: error): Result } Video( val title: String val viewCount: Result<Int> ) apollographql/apollo-kotlin/pull/5405
  21. Client Controlled Nullability graphql/graphql-wg/blob/main/rfcs/ClientControlledNullability.md fragment videoDetails on Video { video

    { # We need title to display a video title! # It's okay to fail viewCount viewCount? } }
  22. string → String string | null → String? string |

    error → String @throws string | null | error → String? @throws Exceptions graphql/nullability-wg/discussions/39
  23. Exceptions string → don’t use string | null → don’t

    use string | error → String string | null | error → String? graphql/nullability-wg/discussions/39