GraphQL参数如何绑定到字段中?

时间:2018-11-07 23:55:52

标签: javascript graphql

我已经阅读了graphql.comhowtographql.com教程上的主要“学习”指南。

我仍在努力解决一些概念,其中一个与论点有关。

基本上,我不了解GraphQL如何知道对象类型的哪个字段(在查询类型中传递的参数属于)。

示例:

type Person {
  id: ID!
  name: String!
  age: Int
  country: String!
}

type Query PersonsByAge {
  person(selectedCountry: String!): [Person]
}

query PersonsByAge {
  person(selectedCountry: 'Sweden')
}

问题

  1. GraphQL如何确切地知道应该在selectedCountry字段上过滤country自变量?
  2. 是否存在多个“对象对象”类型的实例,例如在普通的OOP中,强文本,并且可以像上述一样在List中返回这些实例?
  3. 我不确定我上面的语法/代码是否正确,是否有明显的错误?

我觉得我在这里确实缺少一些基本知识,只是发现指南缺乏深度和结构。

谢谢。


编辑:

修正了括号中的错字,但以理的答案中指出。没有解决其他语法问题,以使答案与问题保持匹配。

1 个答案:

答案 0 :(得分:4)

  1. 为特定字段添加一个或多个参数不会影响该字段本身解析的值。在GraphQL.js中,每个字段都有一个关联的resolve函数(或“解析器”)。由服务器来实现该功能。该函数接收四个参数,包括父字段的值,要解析的字段的参数和执行上下文。解析程序可以使用所有这些参数或不使用这些参数来确定应为字段解析的值。

  2. 是的,GraphQL包含一个称为List的特殊集合类型,它“声明列表中每个项目的类型”。这些可以是输入或输出类型或标量。在GraphQL.js中,列表实际上只是一个数组。重要的是要注意,如果字段的类型是列表,则它的解析器必须返回一个数组,同样,如果字段的类型是输出类型,则解析器不能返回数组。 GraphQL不会将List强制转换为非List值,反之亦然。

  3. 语法有些错误。您的查询带有多余的括号,并且person字段没有子选择(即,您没有为该字段指定要返回的字段,这是必需的,因为该字段的类型是输出类型,而不是标量)。此外,在架构定义中,您在查询类型上有一个多余的PersonsByAge标签,它是无效的语法,并不是真正必需的。

这是您的示例,使用正确的语法和解析器进行了改进,以证明前面的观点。本示例假定您使用graphql-tools创建架构。

const people = [
  { id: 1, name: 'Oscar', country: 'Sweden' },
  { id: 2, name: 'Sal', country: 'Italy' }
]
const typeDefs = `
  type Person {
    id: ID!
    name: String!
    country: String!
  }
  type Query {
    person(id: ID!): Person
    people(selectedCountry: String!): [Person]
  }
`
const resolvers = {
  Query: {
    person: (root, args, context) => {
      // this returns a single object
      return people.find(person => person.id === args.id)
    },
    people: (root, args, context) => {
      // this returns an array
      return people.filter(person => person.country === args.selectedCountry)
    },
  },
}

然后您可以像这样查询架构客户端:

query SomeQueryName {
  people(selectedCountry: "Sweden") {
    id
    name
  }
}

我强烈建议您检出Apollo Launchpad,这将允许您创建模式并即时查询它,以便您可以自由地尝试语法并边做边学。