我有一个像这样的graphQL模式:
type Post {
id: String!
title: String!
content: String!
user: User!
}
type Query {
allPosts: [Post!]
singlePost(id: String!): Post!
}
type User {
name: String!
posts: [Post!]
}
dynamo数据源处理查询。在下面的查询中,将使用不同的解析器处理用户,因为它取决于不同的GSI。
query MyQuery {
allPosts {
content
title
user{
name
}
}
}
allPosts
解析器如下:
{
"version" : "2017-02-28",
"operation" : "Query",
"query" : {
"expression" : "#t = :sk",
"expressionNames" : {
"#t": "type"
},
"expressionValues" : {
":sk": $util.dynamodb.toDynamoDBJson("post")
}
},
"index" : "GSI",
"select" : "ALL_ATTRIBUTES"
}
Post
类型中user
的解析器为:
{
"version" : "2017-02-28",
"operation" : "Query",
"query" : {
"expression" : "PK = :pk AND SK = :sk",
"expressionValues" : {
":pk": "NEED TO ACCESS THE Partition KEY FROM ALL_POSTS",
":sk": $util.dynamodb.toDynamoDBJson("profile")
}
},
"select" : "ALL_ATTRIBUTES"
}
我需要在每次迭代中访问post对象中的分区键,以获取特定id的用户,就像下面代码中的作者解析器一样(https://github.com/benawad/graphql-n-plus-one-example/blob/master/src/index.js):
const resolvers = {
Book: {
author: async parent => {
const author = await knex("users")
.select()
.where("id", parent.authorId)
.first();
return author;
}
},
Query: {
books: async () => {
const books = await knex("books")
.select()
.limit(10);
return books;
}
}
};
我终于找到了答案,所需的对象存储在$ctx.source
中。我所要做的就是把user
解析器改成这样(假设结果对象里面有PK):
{
"version" : "2017-02-28",
"operation" : "Query",
"query" : {
"expression" : "PK = :pk AND SK = :sk",
"expressionValues" : {
":pk": $util.dynamodb.toDynamoDBJson($ctx.source.PK),
":sk": $util.dynamodb.toDynamoDBJson("profile")
}
},
"select" : "ALL_ATTRIBUTES"
}
$context.source
引用正在解析的当前字段的父对象。在本例中,$ctx.source.PK
引用单个Post对象,然后将其用于查询表达式。($context和$ctx是一样的)。它的工作原理与apollo-server
框架中的parent
参数完全相同。