GraphQL子字段查询的根方法

时间:2017-10-19 14:21:56

标签: javascript graphql express-graphql

我是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)
    }
}

我的问题是如何在子字段上实现查询/过滤器。例如:

// 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
    }
}   

感谢阅读!

1 个答案:

答案 0 :(得分:1)

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

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

如果您尝试将帖子限制为返回到特定日期范围,那么为您提供minDatemaxDate参数实际上没有意义时间戳字段。相反,它们应该是posts字段上的参数,就像authorId一样。

您应该在字段中添加参数的唯一时间是您想要更改该字段的解析程序的行为。例如,假设您的帖子类型中有一个字段,如commenters。帖子的评论者列表不会作为您通过调用getPosts()获得的帖子列表的一部分返回 - 而是您需要为每个帖子获取它。如果您想过滤或以其他方式更改提取或返回评论者列表的方式,那么您可以向commenters字段添加一个或多个参数。

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

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

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

请注意,您为参数获取了一个对象 - 它们不会单独传递给解析器。

当您使用根值来定义解析器时,您将无法为除Query,Mutation和Subscription之外的任何类型的字段定义解析器。我建议您考虑使用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
    }
  }
}