本文へスキップ
バージョン: v18.0.0

GraphQL ディレクティブ

Relayは、GraphQLドキュメントに追加情報を付与するディレクティブを使用します。これらのディレクティブは、Relayコンパイラによって適切なランタイムアーティファクトを生成するために使用されます。これらのディレクティブはアプリケーションコードにのみ表示され、GraphQLサーバーに送信されるリクエストからは削除されます。

**注記:** Relayコンパイラは、サーバーでサポートされているディレクティブ(`@include`や`@skip`など)を保持するため、それらはGraphQLサーバーへのリクエストの一部として残り、生成されたランタイムアーティファクトは変更されません。

@arguments

@argumentsは、@argumentDefinitionsを使用して定義されたフラグメントに引数を渡すために使用されるディレクティブです。例:

query TodoListQuery($userID: ID) {
...TodoList_list @arguments(count: $count, userID: $userID) # Pass arguments here
}

@argumentDefinitions

@argumentDefinitionsは、フラグメントが受け取る引数を指定するために使用されるディレクティブです。例:

fragment TodoList_list on TodoList
@argumentDefinitions(
count: {type: "Int", defaultValue: 10} # Optional argument
userID: {type: "ID"} # Required argument
) {
title
todoItems(userID: $userID, first: $count) {
# Use fragment arguments here as variables
...TodoItem_item
}
}

指定された変数

指定された変数は、特別なフラグメント変数であり、その値はランタイム時に指定されたプロバイダ関数によって供給されます。これにより、デバイス属性、ユーザー実験フラグ、その他のランタイム定数をGraphQLフラグメントに簡単に供給できます。

指定された変数を追加するには

  • provider: "[JSModule].relayprovider"@argumentDefinitionsに追加します。
  • [JSModule].relayprovider.jsが存在し、get()関数をエクスポートすることを確認します。
    • getは、特定の実行に対して、すべての呼び出しで同じ値を返す必要があります。
fragment TodoItem_item on TodoList
@argumentDefinitions(
include_timestamp: {
type: "Boolean!"
provider: "Todo_ShouldIncludeTimestamp.relayprovider"
}
) {
timestamp @include(if: $include_timestamp)
text
}
// Todo_ShouldIncludeTimestamp.relayprovider.js
export default {
get(): boolean {
// must always return true or false for a given run
return check('todo_should_include_timestamp');
},
};

注意事項

  • フラグメントがargumentDefinitionsで指定された変数を宣言していても、その親は@argumentsを介して指定された変数を渡すことはできません。
  • 引数定義では、プロバイダとdefaultValueの両方を指定することはできません。
  • 不安定/変更される可能性があります
    • Relayは指定された変数を操作ルート変数に変換し、__relay_internal__pv__[JsModule]に名前変更します。
      • 指定された変数を使用するクエリをデバッグする場合にのみ関連します。

@catch

@catchは、Relayクエリ内のフィールドに追加して、ランタイムでのフィールドレベルの例外の処理方法を宣言できるディレクティブです。

こちらも参照してください `@catch`ガイド.

@connection(key: String!, filters: [String])

usePaginationFragmentを使用する場合、Relayは接続フィールドに@connectionディレクティブが注釈されていることを期待します。詳細情報と例については、usePaginationFragmentに関するドキュメントを参照してください。

@refetchable(queryName: String!, directives: [String], preferFetchable: Boolean)

useRefetchableFragmentusePaginationFragmentを使用する場合、Relayは@refetchableディレクティブを期待します。@refetchableディレクティブは、「再取得可能」なフラグメント、つまり、ViewerまたはQueryタイプ、またはNodeを実装するタイプ(つまり、idを持つタイプ)で宣言されたフラグメントにのみ追加できます。@refetchableディレクティブは、指定されたqueryNameを使用してクエリを自動生成します。これにより、生成されたファイルからインポートできるクエリ用のFlowタイプも生成されます: <queryName>.graphql.js。詳細情報と例については、useRefetchableFragmentまたはusePaginationFragmentに関するドキュメントを参照してください。

オプションで、自動生成されたクエリに追加するディレクティブのリストを渡すことができます。たとえば、これはテストのために@relay_test_operationディレクティブを追加するために使用できます。

[オプション] preferFetchable: Boolean

この引数は、Relayコンパイラに、Nodeインターフェースを実装するタイプに対してfetch_MyType(): MyTypeクエリを生成することを優先するように指示します。これは、タイプに対して@strongおよび@fetchableサーバーアノテーションを採用したスキーマに役立ちます。Nodeインターフェースを特定のタイプに絞り込む必要なく、具体的なオブジェクトを直接取得できます。

graphql`
fragment FriendsListComponent_user on User
@refetchable(
queryName: "FriendsListFetchQuery"
directives: ["@relay_test_operation"]
) {
...
}
`;

@relay(plural: Boolean)

フラグメントコンテナで使用するためのフラグメントを定義する際に、@relay(plural: true)ディレクティブを使用して、コンテナがそのフラグメントのプロップを単一のアイテムではなくアイテムのリストとして期待することを示すことができます。@relay(plural: true)フラグメントを展開するクエリまたは親は、複数フィールド(つまり、GraphQLリストによってサポートされているフィールド)内でそうする必要があります。例:

// Plural fragment definition
graphql`
fragment TodoItems_items on TodoItem @relay(plural: true) {
id
text
}
`;

// Plural fragment usage: note the parent type is a list of items (`TodoItem[]`)
fragment TodoApp_app on App {
items {
// parent type is a list here
...TodoItem_items
}
}

@required

@requiredは、Relayクエリ内のフィールドに追加して、ランタイムでのnull値の処理方法を宣言できるディレクティブです。

こちらも参照してください `@required`ガイド.

@throwOnFieldError

@throwOnFieldErrorは、クエリまたはフラグメントの読み取り時にフィールドエラーが発生した場合にRelayが例外をスローするように、Relayクエリとフラグメントに追加できるディレクティブです。このディレクティブを追加すると、Relayはスキーマで@semanticNonNullとしてマークされたフィールドに対してnull以外の型を生成できます。

こちらも参照してください `@throwOnFieldError`ガイド.

Relayの実験的なサポートについて詳しくは、セマンティックなnull許容性をご覧ください。

@semanticNonNull

@semanticNonNullディレクティブは、スキーマ内のフィールドに追加して、そのフィールドがセマンティックな意味ではnull許容ではないが、クライアントはそれでもエラーを処理する準備をする必要があることを示すことができます。

Relayの実験的なサポートについて詳しくは、セマンティックなnull許容性をご覧ください。

@alias

@aliasは、フィールドエイリアスと同様に、フラグメント展開またはインラインフラグメントにエイリアスを付けることができるディレクティブです。これは、フラグメントを条件付きで含めて取得されたかどうかを確認する場合、またはデータをグループ化する必要がある場合に便利です。

フラグメント展開の場合、エイリアスはフラグメント名にデフォルト設定されます。インラインフラグメントの場合、エイリアスは型名にデフォルト設定されます。独自の名称を指定する場合、または型条件のないインラインフラグメントがある場合は、`as`引数を使用してエイリアスを指定できます。

fragment MyFragment on User {
... on User @alias(as: "myGreatAlias") {
name
}
}

こちらも参照してください `@alias`ガイド.

@inline

Relayが公開するフックAPIを使用すると、レンダリングフェーズでのみストアからデータを読み取ることができます。レンダリングフェーズ外(またはReact外)からデータを読み取るために、Relayは@inlineディレクティブを公開しています。@inlineで注釈されたフラグメントのデータは、readInlineDataを使用して読み取ることができます。

以下の例では、関数processItemDataはReactコンポーネントから呼び出されます。特定のフィールドセットを持つitemオブジェクトが必要です。この関数を使用するすべてのReactコンポーネントは、この関数に必要なすべてのアイテムデータが読み込まれるように、processItemData_itemフラグメントを展開する必要があります。

import {graphql, readInlineData} from 'react-relay';

// non-React function called from React
function processItemData(itemRef) {
const item = readInlineData(
graphql`
fragment processItemData_item on Item @inline {
title
price
creator {
name
}
}
`,
itemRef,
);
sendToThirdPartyApi({
title: item.title,
price: item.price,
creatorName: item.creator.name,
});
}
export default function MyComponent({item}) {
function handleClick() {
processItemData(item);
}

const data = useFragment(
graphql`
fragment MyComponent_item on Item {
...processItemData_item
title
}
`,
item,
);

return <button onClick={handleClick}>Process {item.title}</button>;
}

@relay(mask: Boolean)

@relay(mask: false)の使用はお勧めしません。代わりに、@inlineフラグメントの使用を検討してください。

@relay(mask: false)は、データマスキングを防ぐために使用できます。フラグメントを含めて@relay(mask: false)で注釈を付けると、そのデータは異なるコンテナのためにマスクされるのではなく、親に直接使用できるようになります。

フラグメント定義に適用された@relay(mask: false)は、同じディレクティブでフラグメントが含まれている場合に、生成されたFlowタイプをより使いやすく変更します。Flowタイプは厳密なオブジェクトではなくなり、内部マーカーフィールドを含まなくなります。

これは、単一のコンポーネント内のネストされたデータまたは再帰的なデータに対処する場合に、冗長なフラグメントを減らすのに役立つ場合があります。

多くのコンテナで共有される単一のフラグメントを作成することは、一般的に**アンチパターン**と見なされることを覚えておいてください。このディレクティブを乱用すると、アプリケーションでオーバーフェッチが発生する可能性があります。

以下の例では、...Component_internUserが含まれている場合、userプロップには、Relayの通常の動作(それらのフィールドをマスクする)の代わりに、idnameフィールドのデータが含まれます。

graphql`
fragment Component_internUser on InternUser @relay(mask: false) {
id
name
}
`;

@waterfall

Relay Resolvers を使用すると、グラフ内にクライアント定義のエッジを作成し、サーバータイプのオブジェクトを指すことが可能です。これらのエッジフィールドを読み込む際、Relay はエッジのサーバーデータを遅延読み込み(遅延フェッチ)せざるを得ません。そのため、エッジのデータを取得するために、Relay はサーバーに2回目のリクエストを行うことになります。

エディタ上とコードレビューの両方でこのトレードオフを強調するために、Relayコンパイラはこれらのフィールドの読み込みすべてに@waterfallアノテーションを付けることを求めています。

fragment EditPost on DraftPost {
author @waterfall {
name
}
}

詳細は、Relay Resolvers ガイドの戻り値の型セクションを参照してください。


このページは役に立ちましたか?

簡単な質問にお答えいただき、サイトの改善にご協力ください。 いくつかの簡単な質問にお答えください.