【问题标题】:Binding contextual information into a GraphQL type?将上下文信息绑定到 GraphQL 类型?
【发布时间】:2019-02-20 12:38:06
【问题描述】:

假设我有两种 GraphQL 类型:

type Student {
  id: ID!
  name: String!
}

type Classroom {
  id: ID!
  students: [Student!]!
}

type Query {
  classroom(id: ID!): Classroom!
}

那么我可以像这样运行查询:

{
  classroom(id: 1) {
    id
    students {
      id
      name
    }
  }
}

如果设置了正确的解析器,这将返回与特定教室相关联的学生。

但是,假设我想找到一些与学生在课堂上的表现有关的信息,假设:

averageTestScore: Int!
numAbsences: Int!

我假设我需要一个包装器类型,例如:

type ClassroomStudent {
  averageTestScore: Int!
  numAbsences: Int!
  student: Student!
}

我想知道是否有标准化的方法来做到这一点?此外,我有许多现有的查询将Classroom 直接绑定到Student,因此引入ClassroomStudent 将是一个破坏性的API 更改。有没有一种方法可以让我构建我的 API 以允许非常有机地引入这些类型的更改,而不会引入向后不兼容的更改?

感谢您的宝贵时间。

【问题讨论】:

    标签: javascript graphql graphql-js


    【解决方案1】:

    中继兼容模式中的一个常见模式是将类似的字段附加到相关边缘:

    type StudentConnection {
      pageInfo: PageInfo
      edges: [StudentEdge!]!
    }
    
    type StudentEdge {
      cursor: String!
      node: Student!
      averageTestScore: Int!
      numAbsences: Int!
    }
    
    type Classroom {
      students: StudentConnection!
      # other fields
    }
    

    但是,这实际上仍然与您提出的引入ClassroomStudent 相同。无论哪种方式,在不破坏 API 的情况下引入此类更改的技巧是保留(并弃用)先前的字段并以不同的名称引入新字段:

    type Classroom {
      students: [Student!]! @deprecated(reason: "Use classroomStudents instead")
      classroomStudents: [ClassroomStudent!]!
      # other fields
    }
    

    它可能看起来不漂亮,但它可以让您的客户端应用程序在不处理重大更改的情况下进行转换。

    另一个潜在的选择:

    type Student {
      performance(classroom: ID!): StudentPerformance
    }
    

    您可以使用必填课堂参数向学生添加字段。如果与学生一起查询特定教室,这会迫使客户端可能两次提供相同的教室 ID,但这是一个有效的选项。它还有一个额外的好处是允许您直接查询学生,而不必获取课堂数据:

    query {
      students {
        id
        performance(classroom: 1) {
          averageTestScore
          numAbsences
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-09
      • 2019-02-26
      • 1970-01-01
      • 1970-01-01
      • 2020-04-21
      • 2020-10-03
      相关资源
      最近更新 更多