我有一个DynamoDB表,其中包含客户端所需的所有数据,但是,我希望对客户端接收的数据进行格式化,以减少客户端的操作。
我的模式:
type StateCounty {
id: ID!
StateName: String
CountyName: String
FIPSST: Int
FIPSCNTY: Int
Penetration: String
Date: String
}要返回自定义查询,我有以下类型:
type Query {
getStateCountybyState(StateName: String): StateCountyConnection
}这可以用简单的查询来完成。
query getStateCountybyState {
getStateCountybyState (StateName: "Delaware") {
items {
StateName
CountyName
Date
}
}
} 结果按预期返回:
{
"StateName": "Delaware",
"CountyName": "Kent",
"Date": "02-01-2017"
},
{
"StateName": "Delaware",
"CountyName": "Sussex",
"Date": "02-01-2016"
},
{
"StateName": "Delaware",
"CountyName": "New Castle",
"Date": "02-01-2018"
}等。
我想以下列格式返回数据:
{
"StateName": "Delaware" {
{ "CountyName": "Kent",
"Date": "02-01-2017"
},
{
"CountyName": "Sussex",
"Date": "02-01-2016"
},
{
"CountyName": "New Castle",
"Date": "02-01-2018"
}
}
}我尝试将GroupCounty: StateCountyGroup添加到模式中:
type StateCounty {
id: ID!
StateName: String
CountyName: String
FIPSST: Int
FIPSCNTY: Int
Penetration: String
Date: String
GroupCounty: [StateCountyGroup]
},然后是查询中的引用。
query getStateCountybyState {
getStateCountybyState (StateName: "Delaware") {
items {
StateName
CountyName
Date
GroupCounty: [StateCountyGroup]
}
}
} 我认为我的问题在解析器中--目前,它被配置为使用StateName作为键,但我不知道如何将StateName从主查询传递到子查询。
Resolver:
{
"version" : "2017-02-28",
"operation" : "Query",
"query" : {
"expression" : "StateName = :StateName",
"expressionValues" : {
":StateName" : { "S" : "${context.arguments.StateName}" },
}
},
"index" : "StateName-index-copy",
"select" : "ALL_ATTRIBUTES",
}任何的指导都值得赞赏--我已经看过几次文档,但是找不到一个例子。
更新
我尝试了Richard下面的建议--而且它肯定在正确的轨道上,然而,尽管主题有多种变化,我还是返回null或以下错误(为了简洁起见,我删除了在错误中返回的一些县对象):
"message": "Unable to convert set($myresponse = {\n \"Delaware\":
[{SSA=8000, Eligibles=32295, FIPS=10001, StateName=Delaware, SSACNTY=0,
Date=02-01-2016, CountyName=Kent, Enrolled=3066, Penetration=0.0949,
FIPSCNTY=1, FIPSST=10, SSAST=8, id=6865},
{SSA=8010, Eligibles=91332, FIPS=10003, StateName=Delaware, SSACNTY=10, Date=02-01-2016, CountyName=New Castle, Enrolled=10322, Penetration=0.113, FIPSCNTY=3, FIPSST=10, SSAST=8, id=6866},
{SSA=0, Eligibles=10, FIPS=10, StateName=Delaware, SSACNTY=0, Date=02-01-2018, CountyName=Pending County Designation, Enrolled=0, Penetration=0, FIPSCNTY=0, FIPSST=10, SSAST=0, id=325},
{SSA=8000, Eligibles=33371, FIPS=10001, StateName=Delaware, SSACNTY=0, Date=02-01-2017, CountyName=Kent, Enrolled=3603, Penetration=0.108, FIPSCNTY=1, FIPSST=10, SSAST=8, id=3598},
{SSA=8020, Eligibles=58897, FIPS=10005, StateName=Delaware, SSACNTY=20, Date=02-01-2016, CountyName=Sussex, Enrolled=3760, Penetration=0.0638, FIPSCNTY=5, FIPSST=10, SSAST=8, id=6867}) \nnull\n\n to class java.lang.Object."
}
]
}发布于 2018-04-08 22:32:10
从上面看,听起来您的原始查询返回的是您想要的正确结果,而不是您喜欢的响应格式,因为您希望"StateName“成为顶级JSON键,其值是作为参数传入的状态的JSON对象。这准确吗?如果是,那么为什么不使用已经起作用的查询,但使用不同的响应模板。类似于:
#set($myresponse = {
"$ctx.args.StateName": $ctx.result.items
})
$util.toJson($myresponse)请注意,$myresponse与上面的情况不完全相同,因为"stateName" : "Delaware" { ... }不是完全有效的JSON,所以我不想假设一个好的结构是什么,但问题仍然是,如果您已经从查询中获得了适当的结果,那么我将尝试更改GraphQL结果的结构。
现在,如果我误解了上面的内容,而您没有从查询中获得适当的结果,那么读取您的语句“对子查询的主查询”的另一种方法是,您正在尝试向您的查询结果应用额外的"filter"。如果是这样的话,那么您需要这样的东西:
{
"version" : "2017-02-28",
"operation" : "Query",
"query" : {
"expression" : "StateName = :StateName",
"expressionValues" : {
":StateName" : { "S" : "${context.arguments.StateName}" },
}
},
"index" : "StateName-index-copy",
"select" : "ALL_ATTRIBUTES",
"filter" : {
"expression" : "#population >= :population",
"expressionNames" : {
"#population" : "population"
},
"expressionValues" : {
":population" : $util.dynamodb.toDynamoDBJson($ctx.args.population)
}
}
}我在这里使用了一个示例,在这里您的查询可能还需要根据每个县的人口规模进行筛选。这可能并不代表你正在寻找的东西,但希望它能有所帮助。
编辑与更多信息4/16/18
我已经用一步一步的方式写了更多关于这方面的信息,把这些概念一分为二。
这里的关键不仅仅是响应模板,还包括您请求返回的字段(因为这是GraphQL的本质)。让我们以例子的方式来讨论这件事。现在,您将使用GraphQL返回一个单独的项(因为您的响应模板将数组转换为单个项),因此您需要更改预期的GraphQL查询响应类型。假设您的模式中有一个GraphQL类型,如下所示:
type State {
id: ID!
population: String!
governor: String!
}
type Query {
allStates: [State]
}如果您只是像上面一样在模板中转换响应,那么如果您运行这样的命令,就会看到一个类似于“类型错配错误,预期类型列表”的错误:
query {
allStates{
id
population
}
}这是因为您的响应不再返回各个项目。相反,您需要更改GraphQL响应类型[State],以匹配模板转换所做的State操作,如下所示:
type State {
StateName: String
}
type Query {
allStates: State
}现在,如果解析器请求模板正在执行返回项列表(如DynamoDB扫描或查询)的操作,则可以将列表转换为响应模板中的单个项,如下所示:
#set($convert = {"StateName" : $ctx.result.items })
$util.toJson($convert)然后运行以下GraphQL查询:
query {
allStates{
StateName
}
}然后您将得到一个包含结果数组的单个对象:
{
"data": {
"allStates": {
"StateName": "[{id=1, population=10000, governor=John Smith}]"
}
}
}然而,虽然这可能指出了您正在发生的错误,但这是返回一个StateName,从您最初的问题中,我认为您希望通过将响应中的记录结合起来进行一些优化,并进行一些潜在的筛选,这样可以做得更多。这样做的一种方法是创建一个数组(或者您可以创建一个映射{})并基于某些条件填充它。例如,将查询修改为有一个StateName作为参数:
type Query {
allStates(StateName: String!): Post
}然后,您可以在解析器响应模板中对此进行筛选,方法是使用#foreach和#if()条件,然后只在响应中的项针对所请求的状态调用.add():
#set($convert = {"StateName" : [] })
#foreach($item in $ctx.result.items)
#if($item["StateName"]=="$ctx.args.StateName")
$util.qr($convert.get("StateName").add("$item"))
#end
#end
$util.toJson($convert)所以现在你可以运行这样的程序了:
query {
allStates(StateName:"Texas"){
StateName
}
}这会给你一个特定状态的结果,这是你作为一个论点传递的。但是您会注意到查询的选择集是StateName。通过在GraphQL类型中列出可能的状态,您可以引入更多的灵活性:
type State {
StateName: String
Seattle: String
Texas: String
}现在,您可以修改解析器响应模板,以使用参数来构建返回数组,因为它可以在选择集中指定这一点:
#set($convert = {"$ctx.args.StateName" : [] })
#foreach($item in $ctx.result.items)
#if($item["StateName"]=="$ctx.args.StateName")
$util.qr($convert.get("$ctx.args.StateName").add("$item"))
#end
#end
$util.toJson($convert)因此,我可以运行以下查询:
query {
allPosts(StateName:"Seattle"){
Seattle
}
}我得到了我的结果。注意,虽然传递Seattle作为参数,但请求返回Texas
query {
allPosts(StateName:"Seattle"){
Texas
}
}这不会像您在地图中创建的响应对象是Seattle: [...]一样工作,但是您的选择集是Texas。
您可能要做的最后一件事是返回多个状态,这可以通过构建一个由状态名称键确定的巨大映射来完成,或者使用参数或通过将状态名称添加到返回类型来设置的选择来完成,如上面所示。这取决于你,所以我不知道你会怎么做,但希望这证明了你可以如何操纵响应来满足你的需求。
https://stackoverflow.com/questions/49722910
复制相似问题