摘要: 我正在使用 aws-amplify 生成的 javascript 将查询和突变发送到具有 dynamodb 后端的 AWS graphql 端点。查询/突变功能足够好(它们按预期创建、获取和删除记录)。但他们在这个过程中不断抛出错误:
“查询条件缺少关键架构元素:authorId(服务:AmazonDynamoDBv2;状态代码:400;错误代码:ValidationException;”
我的代码不能太差,不然为什么它能这么好呢?尽管如此,我还是想摆脱这个恼人的错误,或者至少理解它。为什么会出现这个错误?
详细信息:
我的 API 是根据 aws 示例“aws-appsync-chat”中提供的确切 schema.graphql 文件生成的 https://github.com/aws-samples/aws-appsync-chat
模型的相关部分在这里......
type User
@model
@auth(rules: [{ allow: owner, ownerField: "id", queries: null }]) {
id: ID!
username: String!
conversations: [ConvoLink] @connection(name: "UserLinks")
messages: [Message] @connection(name: "UserMessages")
createdAt: String
updatedAt: String
}
遗憾的是,该示例并未真正使用由 amplify 生成的查询和突变。相反,它在文件 src/graphql.js 中使用手写模式。这是正确的。生成的查询/突变包含在项目中,但未实际使用。这让我非常失望。但当我设法重写 JavaScript 逻辑以使其使用由 amplify 生成的查询和突变(或多或少)发挥作用时,我的信心(在某种程度上)恢复了。
无论如何,我采取的第一步是编写以下逻辑:(1)查询用户表以查看当前授权用户是否已存在记录,以及(2)如果授权用户不存在则创建记录。为了加分,我还编写了(3)从数据库中删除用户记录的逻辑。
在 vuejs 组件内部工作,我编写了这些方法...
methods: {
async DeleteUserRecord() {
try {
let id = store.state.user.username;
const input = { id: id };
await API.graphql(graphqlOperation(deleteUser, { input }));// works but throws errors
} catch (err) {
console.log('Error deleting user record:', err)
}
},
async GetUserRecord() {
try {
let id = store.state.user.username;
const result = await API.graphql(graphqlOperation(getUser, { id }));// works but throws errors
console.log(result);
} catch (err) {
console.log('Error getting user record:', err)
}
},
async CreateUserRecord() {
let username = store.state.user.username;
try {
const result = await API.graphql(graphqlOperation(createUser, { input:{ id:username, username: username } })) // works but throws error
console.log(result);
} catch (err) {
console.log('Error creating user record:', err)
}
}
}
这三个似乎都有效,但它们确实会抛出错误,有关详细信息,请参阅随附的屏幕截图。
总是出现同样的错误: “查询条件缺少关键架构元素:authorId(服务:AmazonDynamoDBv2;状态代码:400;错误代码:ValidationException;”
该错误必须与模型中的身份验证规则有关。但请记住,我的代码确实有效,所以我的代码并不完全是垃圾。
谁能给我解释一下这个错误吗?这是 AWS 中的错误吗?还是我的代码写错了?
---------------------------------- 更新如下 ----------- --------------------
我仍然不明白为什么会发生这个错误,但是我在理解它方面取得了一些进展。
如屏幕截图所示,如果我删除要求用户消息的部分,由 amplify 生成的 getUser 查询将起作用。
错误消息中出现的authorId必须来自Message对象的数据模型。
请注意,graphql 模式使用命名连接将消息链接到用户,keyField 为“authorId”。
因此,我可能可以通过修改数据模型中的连接规范来消除该错误。
但是等等。这些是由 amplify 生成的默认查询,只需向其提供完全来自 aws-sample 项目的架构即可。如果不进行编辑,这些查询难道不应该工作得很好吗?
最佳答案
我和你遇到了同样的问题。
我在 github https://github.com/aws-amplify/amplify-cli/pull/1358 中找到了工作示例
type Post @model {
id: ID!
name: String!
comments: [Comment] @connection(name: "PostComments", keyField: "postId", sortField: "statusDate")
}
type Comment @model(queries: null) {
id: ID!
post: Post! @connection(name: "PostComments", keyField: "postId", sortField: "statusDate")
postId: ID!
statusDate: String!
}
@connection 属性两端的 KeyField 必须相同。在 github 教程的示例中,缺少的部分是用户类型中的“authorId”:
type User
@model
@auth(rules: [{ allow: owner, ownerField: "id", queries: null }]) {
id: ID!
username: String!
conversations: [ConvoLink] @connection(name: "UserLinks")
messages: [Message] @connection(name: "UserMessages", keyField: "authorId")
createdAt: String
updatedAt: String
}
此外,Message类型中最好将authorId设置为非空值,因为没有author就无法发布消息。
type Message @model @auth(rules: [{ allow: owner, ownerField: "authorId" }]) {
id: ID!
author: User @connection(name: "UserMessages", keyField: "authorId")
authorId: String!
content: String!
conversation: Conversation! @connection(name: "ConvoMsgs")
messageConversationId: ID!
createdAt: String
updatedAt: String
}
关于javascript - 由 amplify 生成的 Graphql 查询运行良好,但由于身份验证规则而引发错误。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54927684/