---
title: "GraphQLスキーマの作成"
slug: "create-graphql-schemas"
abstract: "GraphQLスキーマプロバイダーの実装方法について説明しています。"
---
# GraphQLスキーマの作成

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

もし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
{
 /// <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エンドポイントとのレジスタジストレーションを備えたスキーマエクステンダーを作成します。これはスキーマプロバイダーに似ています。
    
    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エンドポイントでエクステンダーを登録する方法を示しています。
    
    <?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>