Next.jsを使ったアプリケーションを開発していて、APIからGraphQLプロトコルでデータを取得するところにはApollo Clientを使っています。
表題の通り、Unionの導入の際にデータが取得できなくてハマったので共有です。
こんな風にネストするとうまくいかない
query SomeQuery {
someQuery {
items {
...Info
}
}
}
fragment Info on InfoType {
itemId
firstResult {
...Result
}
secondResult {
...Result
}
}
fragment Result on ResultUnion {
... on PayloadType {
data
}
... on ErrorType {
message
}
__typename
}
このようにUnionのフラグメントをネストした定義でフェッチすると、firstResult
やsecondResult
には__typename
しかフィールドを持たない空のデータがキャッシュされてしまいます。
ネストをやめるとうまくいく
query SomeQuery {
someQuery {
items {
...Info
}
}
}
fragment Info on InfoType {
itemId
firstResult {
... on PayloadType {
data
}
... on ErrorType {
message
}
__typename
}
secondResult {
... on PayloadType {
data
}
... on ErrorType {
message
}
__typename
}
}
このようにネストをやめるとちゃんとデータが入ってくるのですが、最初の例のようにどうしてもフラグメントを使いたい場面はあるかと思います。
解決策
同じ内容のissueを見つけたのですが、
これによると、InMemoryCache
の初期化時に、possibleTypes
にUnionの親子関係を記述するとちゃんとデータを取得できるようです。
new ApolloClient({
...
cache: new InMemoryCache({
...
possibleTypes: {
ResultUnion: [
"PayloadType",
"ErrorType",
],
},
}),
})
無事データがキャッシュされるようになりました。
Apolloの公式ドキュメントにもUnionとInterfaceのフラグメントを使うときはpossibleTypes
を明示する必要があると書かれているので、Interfaceの場合でも同じだと推測されます。