GraphQL Federationを使って段階的に旧システムから新システムに移行しようとしている。 移行に際して、旧システムにリクエストが増えることはオーバヘッド増加の観点で避けたい。 そこで、どのような移行順序なら旧システムへのリクエストを減らせるか調査した。
結論から言うと、グラフとして辿れるならリクエストは増えない。 逆にグラフの途中で新システムへのリクエストが必要な場合に、旧システムへのリクエストが増える。 つまり、エンティティを返すフィールドを考え無しに移行すると旧システムへのリクエストが増える。
具体例を用いて説明する。
前提
旧システムをcurrent、新システムをnewと呼ぶ。
currentのスキーマは次のようになっているとする。
# Itemエンティティ
type Item @key(fields: "id") {
id: ID!
name: String!
tags: [Tag!]!
}
# Tagエンティティ
type Tag @key(fields: "id") {
id: ID!
category: String!
item: Item
}
type Query {
getItem(id: ID!): Item
}
currentへのリクエストが増えない例
グラフとして辿れる場合はcurrentへのリクエストが増えない。今回だと、Item.name をnewに移行しても Item に辿ることに影響しないので問題ない。
次のようなクエリが呼ばれたとする。
query GetItem {
getItem(id: "1") {
name
tags {
item {
name
}
}
}
}
このとき、Item -> Tag -> Item とグラフを辿る必要がある。Item.name を移行してもグラフを辿ることができる。
currentへのリクエストは1回だけ。
query GetItem__current_service__0 {
getItem(id: "1") { # Item に辿れる
__typename
id
tags { # Tag に辿れる
item { # Itemに辿れる
__typename
id
# nameはnewに移行したのでない
}
}
}
}
newへのリクエストは2回。
query GetItem__new_service__1($representations: [_Any!]!) {
_entities(representations: $representations) {
... on Item {
name
}
}
}
query GetItem__new_service__2($representations: [_Any!]!) {
_entities(representations: $representations) {
... on Item {
name
}
}
}
currentへのリクエストが増える例
グラフとして辿れない場合はcurrentへのリクエストが増える。今回だと、Tag.item をnewに移行すると、currentが Item に辿れずリクエストが増える。
次のようなクエリが呼ばれたとする。
query GetItem {
getItem(id: "1") {
name
tags {
item {
name
}
}
}
}
このとき、Item -> Tag -> Item とグラフを辿る必要がある。Item.tags を移行すると Tag -> Item の Item に辿れない。
currentへのリクエストは2回。
query GetItem__current_service__0 {
getItem(id: "1") {
__typename
id
name
tags {
__typename
id
}
}
}
query GetItem__current_service__2($representations: [_Any!]!) {
_entities(representations: $representations) {
... on Item {
name
}
}
}
newへのリクエストは1回。
query GetItem__new_service__1($representations: [_Any!]!) {
_entities(representations: $representations) {
... on Tag {
item {
__typename
id
}
}
}
}
Item -> Tag -> Item の解決が current -> new -> current になり、currentへのリクエストが2回になった。
Query/Mutationを移行すると?
考え方は変わらない。
エンティティを返すフィールドを current に残したままと仮定すると、Query/Mutationを new に移行すると new -> current (-> new)1 となる。
なので、current へのリクエストは増えない。
-
(->
new) はエンティティ以外を返すフィールドが移行済みの場合のパスを示す。↩