嵌套JSON列表

时间:2018-05-21 00:21:22

标签: json graphql apollo

我有一个JSON列表,可以捕获一对多的关系。

例如,School可以有多个Class对象,Class可以有多个Student对象,但Student只属于一个Class和一个School:

{
  "School": [ {
    "id": 1,
    "name": "Grad School",
    "Class": [ {
         "name": 101,
         "Student": [ {
              "name": 501,
              "propertyA": "test"
         }]
     }]
  }]
}

我正在尝试将此JSON示例转换为适当的架构,但嵌套导致问题。阿波罗似乎能够提供帮助,但下面的例子不是很具描述性: https://launchpad.graphql.com/4nqqqmr19

我正在寻找有关如何处理这种情况的建议,无论是通过JSON模式转换器(处理嵌套情况)还是其他方式。

1 个答案:

答案 0 :(得分:2)

我认为你的问题不是模式,对我而言看起来很简单:

你有这些类型(所有虚拟代码,因为你没有在想要提供GraphQL-Api的语言/框架中指定):

SchoolType
  id ID
  name String
  classes [Class]
  students [Students]

ClassType
  id ID
  name String
  school School
  students [Student]

StudentType
  id ID
  name String
  class Class
  school School

然后我们需要一个入口点

classQueryType
  name "school"
  argument :id, ID
  resolve do
    schools.where(id: argument["id"])

所以我们有了架构。更大的工作可能是以上述类型的方式获取不同类型来访问JSON模式。

所以,让我们说,我们用你的结构以某种方式阅读JSON数据。

 const DATA = JSON.parse("your-example.json")

我们需要将其转换为不同的对象集合,因此我们可以动态查询它们:

 schools = []
 classes =  []
 people = []

  def build_schools(data)
    data.schools.for_each do |school|
       schools.push(
         name: school.name, 
         id: school.id, 
         classes: build_classes(school)
       )
    end
 end

 def build_classes(school)
   ids = []
   school.classes.for_each do  |class|
     ids.push(class.id)
     classes.push(
       id: class.id
       name: class.name
       school_id: school.id # you create your own references, to associate these objects
       students: build_students(class)
     )
   end
   return ids
 end

 ...

但是你仍然需要用你的类型系统来解决这个问题。这意味着要编写你的解析器:

例如,在StudentType

StudentType
 id ID
 name String
 class Class
 school School
   resolve(object) ->
     school_id = students.where(id: object.id).class_id.school_id
     schools.where(id: school_id)