どちらも、異種の型のセットを使用してスキーマを設計するのに役立つことを意図しており、両方を使用して同じ機能を実現できますがGraphQLInterfaceType
、型が基本的に同じであるがフィールドの一部が異なる場合、およびGraphQLUnionType
型が異なる場合に適しています。全く違う、全く違う分野を持っています。
最終的には、スキーマの設計に応じて、どちらを使用するかを決定します。
実際の例として、ブログのリストがあり、フレームワーク A を使用するブログは認証としてユーザー名とパスワードを使用し、フレームワーク B を使用するブログは電子メールとパスワードを使用するとします。GraphQLInterfaceType
次のように設計します。
const BlogType = new GraphQLInterfaceType({
name: 'Blog',
fields: {
url: { type: new GraphQLNonNull(GraphQLString) }
password: { type: new GraphQLNonNull(GraphQLString) }
},
resolveType: resolveBlogType
});
const BlogAType = new GraphQLObjectType({
name: 'BlogA',
interfaces: [Blog],
fields: {
url: { type: new GraphQLNonNull(GraphQLString) }
username: { type: new GraphQLNonNull(GraphQLString) },
password: { type: new GraphQLNonNull(GraphQLString) }
}
});
const BlogBType = new GraphQLObjectType({
name: 'BlogB',
interfaces: [Blog],
fields: {
url: { type: new GraphQLNonNull(GraphQLString) }
email: { type: new GraphQLNonNull(GraphQLString) },
password: { type: new GraphQLNonNull(GraphQLString) }
}
});
function resolveBlogType(value) {
return value.username ? BlogAType : BlogBType;
}
を送信する新しいブログをusername
作成すると、BlogA
.
次のようにクエリできます。
query MyQuery {
blogs: {
url
password
... on BlogA {
email
}
... on BlogB {
username
}
}
}
GraphQLUnionType
1 種類のブログと 2 種類の認証方法を使用することを好むため、同じ機能を を使用して取得してみましょう。
const AuthAType = new GraphQLObjectType({
name: 'AuthA',
fields: {
username: { type: new GraphQLNonNull(GraphQLString) },
password: { type: new GraphQLNonNull(GraphQLString) }
}
});
const AuthBType = new GraphQLObjectType({
name: 'AuthB',
fields: {
email: { type: new GraphQLNonNull(GraphQLString) },
password: { type: new GraphQLNonNull(GraphQLString) }
}
});
const AuthType = new GraphQLUnionType({
name: 'Auth',
types: [AuthAType, AuthBType]
resolveType: resolveAuthType
});
const BlogType = new GraphQLInterfaceType({
name: 'Blog',
fields: {
url: { type: new GraphQLNonNull(GraphQLString) }
auth: { type: AuthType }
},
});
function resolveAuthType(value) {
return value.username ? AuthAType : AuthBType;
}
次のようにクエリできます。
query MyQuery {
blogs: {
url
auth {
... on AuthA {
username
password
}
... on AuthB {
email
password
}
}
}
}
この例でわかるように、インターフェースまたは共用体を使用して同じことを達成しますが、スキーマの設計によっては、どちらかがより適切な場合があります。
たとえば、メールとパスワードも使用するブログ フレームワーク C を追加するとします。関数内のブログ フレームワーク B と区別できるようにするには、別のフィールドを含める必要がありresolveBlogType
ます。type
フィールドを追加しましょう。ユニオンの例では、ユニオン内のフィールドにしかアクセスできないためtype
、ユニオンに追加します。将来、複数のフレームワークに同じフィールドを持つ別のユニオンを追加したい場合は、type
そこにもフィールドを追加する必要があります。type
私たちのスキーマで複数回複製したのはあまり良くありません。インターフェースを使用し、インターフェースを使用するすべてのオブジェクトが関数で単一のtype
フィールドにアクセスできるようにすることをお勧めします。resolveBlogType