14

Relay/GraphQL スキーマ構成では、チュートリアルの例のように 1 対多の関係 (ページネーションあり) を指定します。

type ShipConnection {
  edges: [ShipEdge]
  pageInfo: PageInfo!
}
type ShipEdge {
  cursor: String!
  node: Ship
}

ただし、 による 1 対 1 の接続はShipEdge冗長に思えます。カーソルを移動して、IDShipConnectionの配列をShipエッジとして保存できないのはなぜですか?

type ShipConnection {
  edges: [Ship]
  pageInfo: PageInfo!
  cursor: String!
}

edge1 対多のリレーションシップごとに 1 つの追加オブジェクトを要求する設計上の決定はどのようなものでしたか?

4

3 に答える 3

14

(より多くの説明で更新されました)

GraphQL でデータの配列を表す方法は 3 つあります。

  1. リスト: 一度にすべて取得しても問題ない関連オブジェクトのリストが有限である場合に使用します。GraphQL SDL では、これは として表され[Ship]ます。
  2. ノード: 通常、数千のアイテムが存在する可能性があるため、リストをページ分割する必要がある場合に使用します。これは Relay 仕様の一部ではないため、Relay クライアントではサポートされていないことに注意してください (代わりに、#3 で説明されているようにアイテムをエッジでラップします)。ただし、Apollo などの他のクライアントはより柔軟で、この構成をサポートします (ただし、ボイラープレートをさらに提供する必要があります)。GraphQL では、これは として表されtype ShipConnection { nodes: [Ship], pageInfo: PageInfo! }ます。
  3. エッジ: ページネーションに加えて、接続の各エッジに追加情報を提供する必要がある場合に使用します (詳細については以下をお読みください)。GraphQL では、次のように記述しますtype ShipConnection { edges: [ShipEdge], pageInfo: PageInfo! }

GraphQL サーバーは、特定の関連付けに対して 3 つのオプションすべてをサポートしている可能性があり、クライアントは必要なフィールドを選択することに注意してください。これらをすべて組み合わせると、次のようになります。

type Query {
  ships: [Ship]       // #1
  shipsConnection: [ShipConnection]
}

type ShipConnection {
  nodes: [Ship]       // #2
  edges: [ShipEdge]   // #3
  pageInfo: PageInfo!
}

type PageInfo {
  endCursor           // page-based pagination
  hasNextPage
}

type ShipEdge {
  cursor: String!     // edge-based pagination
  node: Ship
  // ... edge attributes
}

type Ship {
  // ... ship attributes
}

リスト (#1) は、アイテムの数が増えないことがわかっている場合にのみ使用する必要があります (たとえば、 がある場合、リストとしてPost返したい場合がありますがtags、 でそれを行うべきではありませんcomments)。#2 と #3 のどちらかを決定するには、単純なノードだけでエッジを使用する理由が 2 つあります。

  • これは、エッジ固有の属性の場所です。たとえば、User多くの に属するがある場合Group、リレーショナル データベースには および を持つ UserGroup テーブルがuser_idありgroup_idます。このテーブルにはrolejoined_atなどの追加の属性GroupUserEdgeを含めることができます。これらの属性にアクセスできる場所は になります。

  • カーソルを置く場所を確保します。ページベースのページネーション ( を使用) に加えて、RelaypageInfoはエッジベースのページネーションをサポートします。Relayがエッジごとにカーソルを必要とするのはなぜですか? Relay はアプリ全体からのデータ要件をインテリジェントにマージするため、リクエストしている同じパラメーターとの接続が既に存在する可能性がありますが、十分なレコードがありません。欠落しているデータを取得するために、エッジのカーソルの後の接続でデータを要求できます。

    データベースにもカーソルがあり、クエリごとにカーソルが 1 つしかないことを考えると、混乱する可能性があることは理解しています。リレー接続は実際にはクエリではなく、クエリを識別する一連のパラメーターです。接続のエッジのカーソルは、接続内の位置を識別するパラメーターのセットです。これは、純粋なクエリ カーソルよりも高い抽象化レベルです (エッジは、DB クエリではない接続やサード パーティ システムによって隠されている可能性がある接続でも位置を識別できる必要があることに注意してください)。この必要な柔軟性のため、1 つの接続に 1 つのカーソルでは不十分です。

于 2015-12-10T03:44:21.063 に答える
9

このedgesフィールドは、エッジごとのデータを配置する場所を提供します。たとえば、誰がエッジを追加したか、関係がどれほど重要であるかをそれぞれ説明する、creatorまたはpriorityフィールドをそこに配置したい場合があります。

この種の柔軟性 (またはページネーションなどの接続で得られるその他の機能) が必要ない場合は、単純GraphQLList型を使用できます。接続とリストの違いの詳細については、この回答を参照してください。

于 2015-10-25T16:29:25.200 に答える
5

単純な GraphQL スキーマと Relay 固有のスキーマの違いに関するブログ記事を書きました。

https://www.prisma.io/blog/connections-edges-nodes-in-relay-758d358aa4c7

于 2016-06-02T12:46:36.857 に答える