假设我有两种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,以允许有机地引入这些类型的更改而又不引入向后不兼容的更改?
谢谢您的时间。
答案 0 :(得分:2)
与中继兼容的模式中的常见模式是将类似字段附加到相关边缘:
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
}
}
}