GraphQLスキーマの作成
このページの翻訳はAIによって自動的に行われました。可能な限り正確な翻訳を心掛けていますが、原文と異なる表現や解釈が含まれる場合があります。正確で公式な情報については、必ず英語の原文をご参照ください。
スキーマは、データを整理および構築する方法を記述します。
Sitecoreインスタンスに、Sitecoreが提供するGraphQLスキーマを通じて公開されていないデータまたはビジネス ロジックが含まれている場合は、独自のスキーマ プロバイダーを作成することをお勧めします。スキーマ プロバイダーを使用して、スキーマの自己完結型の部分を追加できます。
新しいルート クエリを追加する場合、型システムが他のスキーマ プロバイダーの型に依存しない場合は、スキーマ プロバイダーを選択する必要があります。スキーマプロバイダーの良い例は、サードパーティのCRMシステムです。
スキーマ プロバイダーを実装する
スキーマ プロバイダーを実装するには、次のようにします。
-
SchemaProviderBaseクラスを実装するC# クラスを作成します。このクラスは、クエリ可能なルート フィールド (アイテムはコンテンツ スキーマ プロバイダーのルート クエリ フィールドです) を含むGraphQLスキーマの構造を定義します。グラフの種類 (スキーマ内のノードの種類) を定義する他のサポート クラスを作成します。
-
スキーマプロバイダーをGraphQLエンドポイントに登録します。これは、エンドポイントの設定パッチへのタイプ登録です。
次の例は、完全なスキーマ プロバイダーの実装を示しています。これにより、現在のSitecoreユーザーに対してクエリを実行できます。
using System;
using System.Collections.Generic;
using System.Web;
using GraphQL.Resolvers;
using GraphQL.Types;
using Sitecore.Security.Accounts;
using Sitecore.Services.GraphQL.Schemas;
namespace Sitecore.Services.GraphQL.Examples
{
/// <summary>
/// Sample of making your own schema provider
/// This sample enables you to query on the current context user
/// </summary>
public class WhoAmISchemaProvider : SchemaProviderBase
{
public override IEnumerable<FieldType> CreateRootQueries()
{
yield return new WhoAmIQuery();
}
/// <summary>
/// Teaches GraphQL how to resolve the `whoAmI` root field.
///
/// RootFieldType<UserGraphType, User> means this root field maps a `User` domain object into the `UserGraphType` graph type object.
/// </summary>
protected class WhoAmIQuery : RootFieldType<UserGraphType, User>
{
public WhoAmIQuery() : base(name: "whoAmI", description: "Gets the current user")
{
}
protected override User Resolve(ResolveFieldContext context)
{
// this is the object the resolver maps onto the graph type
// (see UserGraphType below). This is your own domain object, not GraphQL-specific.
return Context.User;
}
}
// because this graph type is referred to by the return type in the FieldType above, it is automatically
// registered with the schema. For implied types (e.g. interface implementations) you need to override CreateGraphTypes() and
// manually tell the schema they exist (because no graph type directly refers to those types)
protected class UserGraphType : ObjectGraphType<User>
{
public UserGraphType()
{
// graph type names must be unique within a schema, so if defining a multiple-schema-provider
// endpoint, ensure that you don't have name collisions between schema providers.
Name = "SitecorePrincipal";
Field<NonNullGraphType<StringGraphType>>("name", resolve: context => context.Source.Name);
Field<NonNullGraphType<StringGraphType>>("fullName", resolve: context => string.IsNullOrWhiteSpace(context.Source.Profile.FullName) ? context.Source.Name : context.Source.Profile.FullName);
Field<NonNullGraphType<StringGraphType>>("icon", resolve: context => $"{HttpContext.Current?.Request.Url.GetLeftPart(UriPartial.Authority)}/-/icon/{context.Source.Profile.Portrait}");
Field<NonNullGraphType<BooleanGraphType>>("isAuthenticated", resolve: context => context.Source.IsAuthenticated);
Field<NonNullGraphType<BooleanGraphType>>("isAdministrator", resolve: context => context.Source.IsAdministrator);
// note that graph types can resolve other graph types; for example
// it would be possible to add a `lockedItems` field here that would
// resolve to an `Item[]` and map it onto `ListGraphType<ItemInterfaceGraphType>`
}
}
}
}
この例では、スキーマが小さいため、入れ子になったクラスを使用します。実際のスキーマはサイズが大きいため、RootFieldTypesとGraphTypesを別々のファイルに分割することをお勧めします。
スキーマ プロバイダーをエンドポイントに登録するには、次のようなSitecore設定パッチ ファイルを使用します。
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
<sitecore>
<api>
<GraphQL>
<endpoints>
<master type="Sitecore.Services.GraphQL.Hosting.GraphQLEndpoint, Sitecore.Services.GraphQL">
<schema hint="list:AddSchemaProvider">
<whoDat type="Sitecore.Services.GraphQL.Examples.WhoAmISchemaProvider, Sitecore.Services.GraphQL.Examples.NetFxHost" />
</schema>
</master>
</endpoints>
</GraphQL>
</api>
</sitecore>
</configuration>
GraphQLスキーマの拡張
エクステンダを使用して、既存のスキーマを変更または追加できます。エクステンダはスキーマ プロバイダーの後に処理され、完成したスキーマに型を変更したり追加したりできます。つまり、複数のスキーマ プロバイダーからスキーマを変更または追加できます。スキーマ プロバイダーによって提供される既存の型にフィールドを追加する場合、外部APIを既存の型にフックする場合、またはスキーマ プロバイダーによって提供されるスキーマを変更する場合は、エクステンダを使用します。
エクステンダを使用する良い例は、YouTube動画IDなどのサードパーティのAPI IDを含むアイテムからAPIデータを取得する場合です: YouTube APIを使用して動画の説明を取得し、動画アイテム タイプと一緒にGraphQLで公開できます。
GraphQLスキーマを拡張するには:
-
スキーマ プロバイダーと同様に、SchemaExtenderクラスを拡張するクラスと、構成内のGraphQLエンドポイントへの登録を使用して、スキーマ エクステンダーを作成します。
RequestResponseusing GraphQL.Resolvers; using GraphQL.Types; using Sitecore.Data.Fields; using Sitecore.Services.GraphQL.Schemas; using FieldType = GraphQL.Types.FieldType; namespace Sitecore.Services.GraphQL.Examples { /// <summary> /// Demonstrates some of the power of using schema extenders /// </summary> public class SimpleExtender : SchemaExtender { /// <summary> /// This is a simple example of the capabilities of an extender. It's designed to show the right way to do some common needs. /// </summary> public SimpleExtender() { // Extend the 'Appearance' graph type ExtendType("Appearance", type => { type.Description = "Modified by extender!"; }); // Extend the 'Appearance' graph type, assuming that it is also a derivative of IComplexGraphType // useful because IComplexGraphType is the first type that brings Fields into the type (e.g. not a scalar) ExtendType<IComplexGraphType>("Appearance", type => { // Extend every string field on the type and hack its description ExtendField<StringGraphType>(type, field => { field.Description = "I got hacked by an extender!"; }); // Extend a field by name and tweak its description ExtendField(type, "contextMenu", field => { field.Description = "Yoink! Gotcher description!"; }); }); // extends any type which defines a mapping for the Field backend type // (e.g. all things that represent template fields) ExtendTypes<ObjectGraphType<Field>>(type => { // add a new field to the field object type // note the resolve method's Source property is the Field so you can get at its data type.Field<StringGraphType>("bar", description: "Field added to all fields by an extender", resolve: context => "I'm adding this string to the display name: " + context.Source.DisplayName); }); // Extends three named types and adds a 'foo' field to them ExtendTypes<IComplexGraphType>(new[] { "ItemLanguage", "ItemWorkflow", "ItemWorkflowState" }, type => { // add a "foo" field that returns "foo, bar, bas" to every complex type in the schema // note: using a more specific generic than IComplexGraphType (e.g. ObjectGraphType<T>) may provide // superior options when adding fields like the Field<T> method type.AddField(new FieldType { Name = "foo", Description = "A field passed in from an extender", Resolver = new FuncFieldResolver<string>(context => "foo, bar, bas"), Type = typeof(StringGraphType) }); }); ExtendTypes(type => { // this will be called for _every_ type in the whole schema }); // You can also add graph types, for example, to add complex data as a new field. // This type is added, as opposed to being used. It will appear in the schema // but cannot be queried because it's not attached to any other node in the graph // (for example, as a root query or as a property on another graph type) AddType(() => new FooGraphType()); } protected class FooGraphType : InterfaceGraphType { public FooGraphType() { Name = "Foo"; Field<StringGraphType>("bar"); } } } }
-
次の例は、GraphQLエンドポイントにエクステンダーを登録する方法を示しています。
RequestResponse<?xml version="1.0" encoding="utf-8" ?> <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/"> <sitecore> <api> <GraphQL> <endpoints> <master> <extenders hint="list:AddExtender"> <simpleExtender type="Sitecore.Services.GraphQL.Examples.SimpleExtender, Sitecore.Services.GraphQL.Examples" /> </extenders> </master> </endpoints> </GraphQL> </api> </sitecore> </configuration>