question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support to see if user set field explicitly to `null` on input object

See original GitHub issue

Context I am trying to create a mutation to allow partial updates an object with many nested fields. fun updatePersonInfo(request: UpdatePersonInfo): Profile? nested fields are all optional, so the user only needs to supply fields they want to update in the request.

Fields absent from request will be not be changed. Fields present in the request will be set to the newly values defined in request, including fields set to null.

Example – a mutation to set familyName to “natasha-new-family-name” and middleName to null would look like:

mutation myMutation {
  updatePersonInfo(
    userId: 123,
    personInfo {
      “name”: {
        “familyName”: “natasha-new-family-name”, 
        “middleName”: null
      }
    }
  )
}

a mutation to only update family name, leaving middleName unchanged, would look like:

mutation myMutation {
  updatePersonInfo(
    userId: 123,
    personInfo {
      “name”: {
        “familyName”: “natasha-new-family-name”
      }
    }
  )
}

Problem I am unable to cleanly use graphql-kotlin to see if a user has set a field to null in the mutation input object (indicating desire to delete a field) because there is no way currently to differentiate if a field was set to null by the user, or if it was simply never defined (absent in request).

This is also nature of kotlin itself, undefined fields default to null as the value. However, in graphql there is a difference between undefined and set to null that I am hoping to leverage. https://graphql.github.io/graphql-spec/June2018/#sec-Input-Objects (see: Input Coercion)

Proposed Solution A wrapper class built-in to graphql-kotlin such that a field can have three values to represent it (undefined, null, value). This wrapper would not show up in the schema definition of the object, but would be used to represent if the object it wraps was present in the request or not. If it was present, it’s value is also defined.

Alternatively, leverage java optional wrapper to do this, where the optional wrapper would also not show up in the schema type.

Alternatives Since I do not want the wrapper shown in the schema, my current solution is to parse through the available graphql-java DataFetchingEnvironment instead of using the input object itself (input object still defined for user input) to see if fields are present in the request or explicitly set to null (indicates desire to delete).

As a temporary solution, I wanted to create this wrapper myself, however it would show up in schema. Hoping a built-in optional wrapper supported by graphql-kotlin could help this…

Additional context A similar question has already been asked in this thread: https://github.com/ExpediaGroup/graphql-kotlin/issues/50#issuecomment-483432882 but I feel the root of the problem was never addressed/answered in the original thread.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
dariuszkuccommented, Jul 15, 2020

While it is possible to achieve this with the current hooks it is somewhat problematic, i.e. you could use willGenerateGraphQLType to process the wrapper class but since hooks don’t have access to the generator you would need to manually build underlying GraphQL type (or reference built in scalars). Once schema is generated you would still need to create custom data fetcher to properly unmarshall the incoming object into the wrapper class.

I’m thinking for 4.0.0 we probably could introduce some sealed class to represent defined/undefined state (introduce the unwrapping logic in input object generation and update default data fetcher to properly handle those as well).

0reactions
oatmeal-raisincommented, Jul 22, 2020

@dariuszkuc, @smyrick I was able to get this to work by adding a hook into generateGraphQLType in a local build of graphql-kotlin. The hook was basically the equivalent of willResolveMonad. Leveraging that hook and Jackson’s support for Optional worked in @natashashams and I project. generateGraphQLType is probably no the ideal place for this but it helped me prototype it quickly. It would be great to add a hook that allowed you to unwrap types, even if a built in type will be provided for undefined. These cases would require users to write their own deserializers but it’s a very generic feature that could help as a stepping stone to related wrapper functionality. It would be especially helpful if someone is looking to map to a type that is more natural to deeper layers of their service.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Check if inputs are empty using jQuery - Stack Overflow
If a field is clicked into and then not filled out, I would like to display a red background. Here is my code:...
Read more >
Nullable reference types - Microsoft Learn
Nullable reference types includes three features that help you avoid these exceptions, including the ability to explicitly mark a reference type ...
Read more >
<input>: The Input (Form Input) element - HTML
The HTML element is used to create interactive controls for web-based forms in order to accept data from the user; a wide variety...
Read more >
Avoid Check for Null Statement in Java - Baeldung
So, accessing any field, method, or index of a null object causes a ... This makes it explicit to the client code whether...
Read more >
Template type checking - Angular
If the fullTemplateTypeCheck flag is set to true , Angular is more aggressive ... opt out of strict null type checking specifically for...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found