異機種セットのスキーマを設計するのに役立ちますが、両方を使用して同じ機能を実現できますが、タイプが基本的に同じであるがフィールドのいくつかの場合は、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
を使用して、我々はブログの単に一つのタイプを使用することを好むため、および認証方法の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を追加したいとします。 resolveBlogType
機能では、ブログフレームワークBと区別できるように別のフィールドを含める必要があります。 type
フィールドを追加してみましょう。 Unionの例では、Union内のフィールドにしかアクセスできないため、type
をUnionに追加します。将来、複数のフレームワークに同じフィールドを持つ連合を追加したい場合は、type
フィールドも追加する必要があります。私たちのスキーマでtype
が何度も重複しているのはあまりいいことではありません。インターフェイスを使用し、resolveBlogType
関数でインターフェイスを使用するすべてのオブジェクトによって単一のtype
フィールドにアクセスできるようにすることをお勧めします。
リレーフラグメントで 'blogs'をクエリすると、これはgraphql-wiseに相当しますか?あなたのgraphqlインターフェイスタイプが 'Blog'という名前であることがわかります – maxwell
サンプルコードにないブログのクエリを作成する必要があります –
私はまだ分かりません – arcom