建模中继游标连接

Modeling Relay Cursor Connections

我正在构建一个 graphql 应用程序,其中一个 User 可以有一堆 Entries。这是一个 n 对 m 的关系,中间人 table/edge 持有有关该关系的附加信息。 我的 graphql 模式看起来像这样:

type User {
    id: ID!,
    entries(…): [UserEntry]
}

type UserEntry {
    id: ID!,
    user: User,
    entry: Entry,
    someOtherAttribute: String,
    yetAnotherAttribute: String
}

type Entry {...}

type Query {
  me: User!
  userEntry(userEntryId: ID!): UserEntry!
}

我想在 Relay Cursor Connections Specification 之后的那个 entries 字段中添加光标样式分页。 所以我猜 UserEntry 会变成这样:

type UserEntryEdge {
    node: Entry,
    cursor: String,
    someOtherAttribute: String,
    yetAnotherEdgeAttribute: String
}

但我仍然希望能够直接查询 UserEntry/UserEntryEdge,在这种情况下,例如 cursor 字段将是无关紧要的。

设计我的 graphql 模式以便能够直接查询边数据的最佳方法是什么?

(仅供参考:我在服务器和客户端上都使用 nodejs 和 apollo 框架套件)

如果您仍然需要直接查询 UserEntry 那么我想您应该将它作为一个单独的类型保留在您的架构中,而不是将其转换为 Edge 类型。

所以只保留 UserEntryUserEntryEdge

生成的架构可能如下所示:

type User {
    id: ID!,
    entries(…): [UserEntryConnection]
}

type UserEntryConnection {
  edges: [UserEntryEdge]
  nodes: [Entry] # shortcut (GitHub does like that)
  pageInfo: PageInfo!
}

type UserEntryEdge {
    node: Entry,
    cursor: String,
    info: UserEntry # To not duplicate attributes, you can use UserEntry type here
}

type UserEntry {
    id: ID!,
    user: User,
    entry: Foo,
    someOtherAttribute: String,
    yetAnotherAttribute: String
}

type Entry {...}

type Query {
  me: User!
  userEntry(userEntryId: ID!): UserEntry! # keep userEntry field as is
}

您实际上是这样建模您的模式

[User] hasAndBelongsToMany [Entry]

但你可以这样想

[User] hasMany [UserEntry] hasOne [Entry]
    and
[Entry] hasMany [UserEntry] hasOne [User]

那么,回到您的 GraphQL 模式:

type User {
    id: ID!,
    userEntriesConnection(…): UserEntriesConnection!
}

type UserEntriesConnection {
    edges: [UserEntryEdge]!,
    pageInfo: ...
}

type UserEntryEdge {
    cursor: String!,
    node: UserEntry,
}

type UserEntry {
    id: ID!,
    user: User,
    entry: Entry,
    someOtherAttribute: String,
    yetAnotherAttribute: String
}

type Entry { ... }

type Query {
  me: User!
  userEntry(userEntryId: ID!): UserEntry!
}

这符合您的需要吗?查询会更冗长,因为有更多的深度,但也更完整。