Sitecore GraphQLベストプラクティス

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

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

Sitecore GraphQL APIを使用するときは、次のベストプラクティスに従うことをお勧めします。

コンテキストアウェアエンドポイントを使用する

公開サイトの場合は、データベース コンテキスト対応エンドポイントを使用して、正しいコンテンツ データベース (master/web/etc) を尊重します。これにより、APIは認証モード (プレビュー、エクスペリエンス エディター) で適切なアイテム データを返すようになります。

エンドポイントをコンテキスト対応にするには、次のようにします。

  • エンドポイントがtypeとして定義されていることを確認します Sitecore.Services.GraphQL.Hosting.DatabaseAwareGraphQLEndpoint, Sitecore.Services.GraphQL.NetFxHost

  • ContentSchemaProviderのデータベース設定を構成するときは、実際のデータベース名ではなくcontextに設定します。これにより、Sitecore.Context.Databaseに従うようになります。

  • コンテキスト対応エンドポイントはデータベースごとに異なるスキーマを提供するため、masterに対して検証するクエリは、その背後にあるテンプレートが公開されていない場合、webに対して検証されない可能性があることに注意してください。

  • エンドポイントがデータベース固有のコンテンツを提供していない場合は、コンテキスト対応エンドポイントにしないでください。これは、たとえば、CRMに接続したり、分析データをプッシュしたりするためにのみ指定するエンドポイントです。

公開Webサイトでサブスクリプションを使用しない

公開WebサイトでGraphQLサブスクリプションを使用しないでください。

サブスクリプションは、作成者が使用するContent Managementサーバーのカスタマイズに使用することを目的としています。Sitecoreは、スケーリングされたパブリック環境でのサブスクリプションの使用をサポートしていません。

独自のグラフタイプを実装する

独自のIGraphType実装でフィールドを定義する方法には、多くのオプションがあります。

一般に、最もパフォーマンスが高く、最も柔軟性の高いオプションは、Fieldメソッドを使用し、グラフの種類を明示的に指定し、名前付きリゾルバー関数を使用することです。これにより、エラーが発生したときに適切なスタックトレースを取得できます。次に例を示します。

RequestResponse
// the <ItemState> determines the data object type this graph type maps to
// (in a resolver, context.Source is of this type)
public class ItemWorkflowGraphType : ObjectGraphType<ItemState>
{
    public ItemWorkflowGraphType()
    {
        // ALWAYS set the name. Note that the name must be unique within a schema so be descriptive.
        Name = "ItemWorkflow"; 

        // define your field (note: wrap type in NonNullGraphType<T> if it should never be null)
        Field<ItemWorkflowStateGraphType>("workflowState", resolve: ResolveWorkflowState);

        // this would automatically map to a property on the ItemState called WorkflowState
        // DO NOT use this format, because it causes reflection during queries = slow
        Field<ItemWorkflowStateGraphType>("workflowState");

        // Expression-based resolver. Reasonable performance, non-verbose, but cannot specify
        // the graph type (or its nullablilty), and you do not get nice stack traces on error
        // useful for very simple scalar type resolution (e.g. strings, ints)
        Field("workflowState", state => GetWorkflowState());

        // Sometimes you might not have access to the Field() method, in which case 
        // you can use manual field-adding syntax. This example is equivalent to the first recommended one.
        // Note: DO NOT set the ResolvedType property by accident. This will mess things up.
        AddField(new FieldType
        {
            Name = "workflowState",
            Type = typeof(ItemWorkflowStateGraphType),
            Resolver = new FuncFieldResolver<ItemState, WorkflowState>(ResolveWorkflowState)
        });
    }

    // explicit named resolver function means that you will see a reasonable stack trace if a resolve error occurs
    // (as oppposed to an anonymous function in the constructor)
    private WorkflowState ResolveWorkflowState(ResolveFieldContext<ItemState> context)
    {
        return context.Source.GetWorkflowState();
    }
}

任意の階層の処理

データの種類によっては、特に任意にネストされた階層など、GraphQLで使いにくいものがあります。

たとえば、アイテムのすべての子孫を取得する必要があり、子のレベル数が不明な場合、必要なグラフの部分を指定する必要があるため、GraphQLはこれをサポートしていません。

別のケースとして、フィールドのセットを常にまとめたい場合や、まったく組み合わせない場合などがあります (たとえば、レンダリングツールキットで使用される任意のJSONのブロックで、ユーザーにGraphQLフラグメントを記憶させたくない場合など)。この場合、JsonGraphTypeを使用できます。このタイプを使用すると、任意のJSONをGraphQLフィールドとして返すことができます。これは、グラフがデータを適切に表現できない場合の最後の手段です。JsonGraphTypeのリゾルバーは、任意のオブジェクト (シリアル化) またはJToken (そのまま使用) を返すことができます。

JsonGraphTypeは入力グラフタイプとしても使用でき、その場合は値をエスケープされた文字列として渡す必要があります。これは、実際のJSONがエスケープされずに返される出力タイプとは異なります。

フロントエンドからGraphQL APIを消費します

フロントエンドからGraphQL APIを使用する場合は、次のことをお勧めします。

  • フロントエンドサイトまたはアプリケーションにGraphQL APIを使用する場合は、常にそのサイトに対して独自のエンドポイントを定義します。これにより、APIの攻撃対象領域、認証、URLをきめ細かく制御できます。APIはできるだけ小さく公開します。

  • スキーマ プロバイダー ( ContentSchemaProviderなど) を再利用します (既に存在する場合)。

  • クエリを .graphqlファイルに分割します。それらをコードと混同しないでください。

    • これにより、懸念事項が適切に分離され、次のようなツールを使用graphql-tag/loader、JavaScriptファイルと同じ方法でファイルをインポートできます。

    • 静的に分析可能なクエリを使用すると、ビルド時にすべてのクエリを検証したり、セキュリティ ホワイトリストを実行したり、その他の一般的な操作を実行したりすることが容易になります。

    • これが不可能な場合 (たとえば、現在Angularでは、ビルドをカスタマイズしてGraphQLローダーを追加することはできません)、クエリを .jsファイルまたはAngularコンポーネントのmycomponent.graphql.tsなど、クエリのみを含む .tsファイルに分割します。

  • 動的な文字列連結クエリ (クエリ テキストにGraphQL以外の変数を含む) は使用しないでください。クエリ変数は、常にGraphQLクエリ変数である必要があります。

    • これは、ホワイトリスト、静的分析、パフォーマンス分析を打ち負かし、一般的には悪い考えです。

  • クエリのバッチ処理を利用します。

    • RESTに対するGraphQLの大きな利点の1つは、GraphQLがプロトコルであるため、RESTでは実行できない一部の操作が可能になることです。

    • クエリのバッチ処理により、複数のクエリ (短時間内に行われた) を1つのHTTP要求に自動的に結合できます。

  • ツールを使用して、GraphQLクエリがGraphQLスキーマに対して有効であることを確認します( eslint-plugin-graphqlなど)。

    • これにより、ビルド時の安全性が確保され、クエリ式が有効であり、実行時に中断されません。

GraphQLツールでSitecore GraphQLを使用する

多くの種類のGraphQLツール (ビルド時にクエリを検証するeslint-plugin-graphql 、切断されたモックGraphQL APIを作成するgraphql-tools 、TypeScriptでGraphQLのコード補完を提供するts-graphql-pluginなど) には、GraphQLのコピーが必要です正しく実行するためのスキーマ。場合によっては、これをSitecoreインスタンスから直接ダウンロードして、ライブ スキーマを持つことができます。ただし、それ以外の場合はライブSitecoreインスタンスがないため、スキーマの静的コピーが必要です。

スキーマ入力には、主に2つのタイプがあります。

  • JSON形式のスキーマ。これは、GraphQL APIに対するイントロスペクションクエリの結果です。これは、GraphiQLがブラウザにドキュメントを提供するなどに使用するものです。

  • スキーマ定義言語スキーマ。これは、スキーマを読み取り可能な形式で定義するテキスト形式です。これをダウンロードするには、$endpointUrl/schemaにアクセスしてコンテンツを取得し、.graphqlファイルとして保存します。

Sitecoreの設定の変更 (テンプレートの変更や追加など) により、GraphQLスキーマが変更されます。静的スキーマファイルを使用する場合は、誤った検証を避けるために、常に最新の状態に保たれるようにする必要があります。

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

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