javascript - 由 amplify 生成的 Graphql 查询运行良好,但由于身份验证规则而引发错误。为什么?

标签 javascript vuejs2 amazon-dynamodb graphql aws-amplify

摘要: 我正在使用 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)
        }
    }
  }

这三个似乎都有效,但它们确实会抛出错误,有关详细信息,请参阅随附的屏幕截图。

Console errors screenshot

总是出现同样的错误: “查询条件缺少关键架构元素:authorId(服务:AmazonDynamoDBv2;状态代码:400;错误代码:ValidationException;”

该错误必须与模型中的身份验证规则有关。但请记住,我的代码确实有效,所以我的代码并不完全是垃圾。

谁能给我解释一下这个错误吗?这是 AWS 中的错误吗?还是我的代码写错了?

---------------------------------- 更新如下 ----------- --------------------

我仍然不明白为什么会发生这个错误,但是我在理解它方面取得了一些进展。

  1. 如屏幕截图所示,如果我删除要求用户消息的部分,由 amplify 生成的 getUser 查询将起作用。

  2. 错误消息中出现的authorId必须来自Message对象的数据模型。

  3. 请注意,graphql 模式使用命名连接将消息链接到用户,keyField 为“authorId”。

因此,我可能可以通过修改数据模型中的连接规范来消除该错误。

但是等等。这些是由 amplify 生成的默认查询,只需向其提供完全来自 aws-sample 项目的架构即可。如果不进行编辑,这些查询难道不应该工作得很好吗?

Garphql Schema Working Query Failing Query

最佳答案

我和你遇到了同样的问题。

我在 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/

相关文章:

javascript - 通过纯 JavaScript 更新 CSS ...如果属性使用 vendor 前缀,我该如何更新?

javascript - 我想使用 Javascript 来放置 Php 函数

vue.js - 'slot activator' 在 vuetify 中如何工作?

amazon-dynamodb - 如何在单个请求中放置多个项目?

json - 使用 AWS Rekognition 检测 PPE 并将结果存储在 DynamoDB 中

javascript - RxJS 取消嵌套回调

javascript - 单击项目后关闭抽屉导航?

javascript - Vue - 响应式媒体 .readyState

json - Vue 变量在页面顶部转储所有数据以进行测试

node.js - 在 dynamodb Local 中查询全局二级索引