protocol buffers – How can I define and resolve a GraphQL union type that maps to a google protobuf Oneof field?

Environment:

  • frontend: nestJS, apollo graphQL, react typescript
  • backend: protobuf messages, java

I am trying to resolve a union type in GraphQL using data from backend sent from protobuf “oneof” types, and running into some difficulties… Does anyone have experience with the same?

thanks for reading through the example! I know it’s a bit long… appreciate any pointers!!

for example:
given this protobuf definition:

message Digest {
  int32 digestId = 1;
  string digestContent = 2;
}
 
message Alert {
  string alertMsg = 1;
}

message ContentWrapper {
  oneof content {
    Digest digest = 1;
    Alert alert = 2;
    string generic = 3;
  }
}

the backend response for a list of ContentWrapper items would look like:

{
  digest: {
    digestId: 4588283,
    digestContent: 'testmsgasdasdasd'
  },
  alert: undefined,
  generic: undefined
},
{
  alert: {
    alertMsg: 'testmsgasdasdasd'
  },
  digest: undefined,
  generic: undefined
}

and with the corresponding union type

type ContentWrapper {
  content: ContentUnion
}
 
union ContentUnion =
    Digest
  | Alert
  | String
 
type Digest {
  digestId: Int
  digestMsg: String
}
 
type Alert {
  alertMsg: String
}

how would I write my resolveType function?
the problem is in the data returned by backend, there is no content field that I can access directly, but rather just each individual possible fields…

therefore, when I try to resolve ContentWrapper item, I can’t do things like:

_resolveType(obj, contextValue, info){
      if(obj.digestId){
        return 'Digest';
      }
      if(obj.alertMsg){
        return 'Alert';
      }
      return null; // GraphQLError is thrown
    },

because obj is actually the entire ContentWrapper =

{
  digest: {
    digestId: 4588283,
    digestContent: 'testmsgasdasdasd'
  },
  alert: undefined,
  generic: undefined
}

rather than just the nested field of the union types…

Read more here: Source link