GraphQLスキーマの作成

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

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

スキーマは、データの整理や構築の仕方を記述します。

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

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

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

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

  1. SchemaProviderBaseクラスを実装するC#クラスを作成します。このクラスはGraphQLスキーマの構造を定義し、クエリ可能なルートフィールドも含みます(アイテムはコンテンツスキーマプロバイダーのルートクエリフィールドです)。グラフタイプ(スキーマ内のノードタイプ)を定義する他のサポートクラスを作成します。
  2. 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 { ///

/// Sample of making your own schema provider /// This sample enables you to query on the current context user /// public class WhoAmISchemaProvider : SchemaProviderBase { public override IEnumerable CreateRootQueries() { yield return new WhoAmIQuery(); }

///

/// 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. /// 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 { 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>("name", resolve: context => context.Source.Name); Field<NonNullGraphType>("fullName", resolve: context => string.IsNullOrWhiteSpace(context.Source.Profile.FullName) ? context.Source.Name : context.Source.Profile.FullName); Field<NonNullGraphType>("icon", resolve: context => $"{HttpContext.Current?.Request.Url.GetLeftPart(UriPartial.Authority)}/-/icon/{context.Source.Profile.Portrait}"); Field<NonNullGraphType>("isAuthenticated", resolve: context => context.Source.IsAuthenticated); Field<NonNullGraphType>("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` } } } }

!注この例ではスキーマが小さいため、ネストされたクラスを使用しています。実際のスキーマはより大きくなり、RootFieldTypesとGraphTypesを別々のファイルに分割することをお勧めします。

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

## GraphQLスキーマの拡張

エクステンダーを使って既存のスキーマを修正または追加することができます。エクステンダーはスキーマプロバイダーの後に処理され、完成したスキーマに型を追加または修正できます。つまり、複数のスキーマプロバイダーからスキーマを修正または追加することができます。エクステンダーは、スキーマプロバイダーが提供する既存型にフィールドを追加したり、外部APIを既存の型にフックしたり、スキーマプロバイダが提供するスキーマを修正したりします。

エクステンダーを使う良い例としては、YouTubeの動画IDのようなサードパーティAPI IDを含むアイテムからAPIデータを取得したい場合です。YouTube APIを使って動画の説明を取得し、動画アイテムタイプと並べてGraphQLで露出させることができます。

GraphQLスキーマを拡張するには:

  • SchemaExtenderクラスを拡張するクラスと、設定中のGraphQLエンドポイントとのレジスタジストレーションを備えたスキーマエクステンダーを作成します。これはスキーマプロバイダーに似ています。

    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 { ///

    /// Demonstrates some of the power of using schema extenders /// public class SimpleExtender : SchemaExtender { /// /// This is a simple example of the capabilities of an extender. It's designed to show the right way to do some common needs. /// 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("Appearance", type => { // Extend every string field on the type and hack its description ExtendField(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>(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("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(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) may provide // superior options when adding fields like the Field method type.AddField(new FieldType { Name = "foo", Description = "A field passed in from an extender", Resolver = new FuncFieldResolver(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("bar"); } } } }

  • 以下の例は、GraphQLエンドポイントでエクステンダーを登録する方法を示しています。

この記事を改善するための提案がある場合は、 お知らせください!