Skip to content

Client generated graphql interface type contains partial fields #531

@AlistairB

Description

@AlistairB

The fix for #509 enables using graphql interfaces and sub types in the client. However, it does so in a way that creates partial record accessors.

https://github.com/AlistairB/morpheus-repro/tree/partial-fields demonstrates the issue. stack build will produce the warning (it uses morpheus 0.15.0). In this case it generates the type:

data RepositoryObjectGitObject
  = RepositoryObjectGitObject {__typename :: Text} |
    RepositoryObjectBlob {__typename :: Text,
                          isTruncated :: Bool,
                          text :: (Maybe Text)}
  deriving Generic
  deriving Show
  deriving Eq

The reason this can be of concern is isTruncated and text are now partial functions. For example, isTruncated (RepositoryObjectGitObject "blah") will compile but will generate a runtime error. How much of an issue this is is debatable. -Wpartial-fields is not enabled by -Wall, however I think it is still popular.

One solution is just to exclude the accessors, but this would get ugly if you had a lot of fields returned (you might pattern match on MyComplexType Text Text Text Text Int Int Int etc which would be error prone). I think the ideal solution would be something like:

data RepositoryObjectGitObject
  = RepositoryObjectGitObject RepositoryObjectGitObjectValues
  | RepositoryObjectBlob RepositoryObjectBlobValues
  deriving (Generic)
  deriving (Show)
  deriving (Eq)

data RepositoryObjectGitObjectValues = RepositoryObjectGitObjectValues {repositoryObjectGitObjectValues__typename :: Text}

data RepositoryObjectBlobValues = RepositoryObjectBlobValues
  { repositoryObjectBlobValues__typename :: Text, -- actually we need to prefix this now as there can't be overlapping `__typename`. Unless DuplicateRecordFields is enabled.
    isTruncated :: Bool,
    text :: (Maybe Text)
  }

This way you are forced to pattern match on the interface / sub types which is total, but can then use the sub types as normal records with accessors.

I might have some time to work on this, if you know what the ideal behaviour should be.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestgood first issueGood for newcomers📦 clientLabel for affected Package: "morpheus-graphql-client"

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions