GraphQLスキーマの作成

Version: 22.x
日本語翻訳に関する免責事項

このページの翻訳はAIによって自動的に行われました。可能な限り正確な翻訳を心掛けていますが、原文と異なる表現や解釈が含まれる場合があります。正確で公式な情報については、必ず英語の原文をご参照ください。

スキーマは、データを整理および構築する方法を記述します。

Sitecoreインスタンスに、Sitecoreが提供するGraphQLスキーマを通じて公開されていないデータまたはビジネス ロジックが含まれている場合は、独自のスキーマ プロバイダーを作成することをお勧めします。スキーマ プロバイダーを使用して、スキーマの自己完結型の部分を追加できます。

新しいルート クエリを追加する場合、型システムが他のスキーマ プロバイダーの型に依存しない場合は、スキーマ プロバイダーを選択する必要があります。スキーマプロバイダーの良い例は、サードパーティのCRMシステムです。

スキーマ プロバイダーを実装する

スキーマ プロバイダーを実装するには、次のようにします。

  1. SchemaProviderBaseクラスを実装するC# クラスを作成します。このクラスは、クエリ可能なルート フィールド (アイテムはコンテンツ スキーマ プロバイダーのルート クエリ フィールドです) を含むGraphQLスキーマの構造を定義します。グラフの種類 (スキーマ内のノードの種類) を定義する他のサポート クラスを作成します。

  2. スキーマプロバイダーをGraphQLエンドポイントに登録します。これは、エンドポイントの設定パッチへのタイプ登録です。

次の例は、完全なスキーマ プロバイダーの実装を示しています。これにより、現在のSitecoreユーザーに対してクエリを実行できます。

RequestResponse
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>`
            }
        }
    }
}
メモ

この例では、スキーマが小さいため、入れ子になったクラスを使用します。実際のスキーマはサイズが大きいため、RootFieldTypesGraphTypesを別々のファイルに分割することをお勧めします。

スキーマ プロバイダーをエンドポイントに登録するには、次のようなSitecore設定パッチ ファイルを使用します。

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 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エンドポイントへの登録を使用して、スキーマ エクステンダーを作成します。

    RequestResponse
    using 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>
    

何かフィードバックはありますか?

この記事を改善するための提案がある場合は、