GraphQL 子字段查询的根方法

Root Methods for GraphQL Sub Field Queries

我是 GraphQL 的新手,不确定如何在子字段上实现查询。

例如,假设我们有以下类型和查询:

type Author {
    joinedDate: String,
    quote: String
}

type Post {
    id: String,
    author: Author,
    text: String,
    timeStamp: String,
    location: String
}

type Query {
    posts(authorId: String): [Post]
}

客户随后可以提出如下请求:

// gets everything
{
    posts(authorId: Steve)
}
// just gets time, text, and location
{
    posts(authorId: Steve) {
        timeStamp
        text
        location
    }
}    

根对象可以这样实现:

const root = {
    posts: (authorId) => {
        return dataService.getPosts(authorId)
    }
}

我的问题是您将如何在子字段上实施 queries/filters。例如:

// just gets time, text, and location for specific date range
{
    posts(authorId: Steve) {
        timeStamp(minDate: 01012015, maxDate: 10102018)
        text
        location
    }
}

我将如何定义根方法?我是否需要在 posts root 方法中手动过滤完整的帖子列表?

const root = {
    // would this method even have access to the date args?
    posts: (authorId, minDate, maxDate) => {
        const newList = filterTheList(
            dataService.getPosts(authorId),
            minDate,
            maxDate
        )
        return newList
    }
}   

感谢阅读!

如果 dataService.getPosts() 没有为您提供一些方法来传递过滤器并且您不能修改该代码,那么,是的,您必须自己过滤结果,然后再将它们返回到解析器。

否则,如果 dataService 只是查询数据库,您只需重构 getPosts() 以根据传递给它的参数将数据库查询限制为一个子集。

如果您试图将返回的 posts 限制在特定日期范围内,那么 minDatemaxDate 时间戳字段的参数。相反,它们应该是 posts 字段的参数,就像 authorId.

只有当您想要更改该字段的解析器的行为时,您才应该向字段添加参数。例如,假设您在 Post 类型上有一个字段,例如 commenters。 post 的评论者列表不会作为您通过调用 getPosts() 获得的 post 列表的一部分返回——相反,您需要为每个 post 获取它].如果您想过滤或以其他方式更改获取或返回评论者列表的方式,那么您可以向 commenters 字段添加一个或多个参数。

为了更直接地解决您的问题,传递给您的解析器的参数只是该特定字段的参数——您的 posts 解析器不会获取其下字段的参数。

最后但同样重要的是,在编写解析器时,请记住传递给它的参数。如果您使用根值来定义解析器,则解析器如下所示:

const root = {
  posts: (args, context, info) => {
    //args.authorId
  }
}

请注意,您的参数只有一个对象——它们不会单独传递给解析器。

当您使用根值定义您的解析器时,您将无法为除查询、变更和订阅之外的任何类型的字段定义解析器。我鼓励您考虑使用 graphql-tools' makeExecutableSchema。它简化了架构的构建,同时仍提供灵活性。

使用 makeExecutableSchema,您的解析器将如下所示:

const resolvers = {
  Query: {
    posts: (obj, args, context, info) => {}
  },
  Post: {
    someField: (obj, args, context, info) =>{
      //obj here will be the obj a specific Post was resolved to
    }
  }
}