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

Posted

技术标签:

【中文标题】由 amplify 生成的 Graphql 查询运行良好,但由于身份验证规则而引发错误。为啥?【英文标题】:Graphql queries generated by amplify work well, but throw errors due to auth rules. Why?由 amplify 生成的 Graphql 查询运行良好,但由于身份验证规则而引发错误。为什么? 【发布时间】:2019-07-22 11:39:56 【问题描述】:

总结: 我正在使用 aws-amplify 生成的 javascript 将查询和突变发送到具有 dynamodb 后端的 AWS graphql 端点。查询/突变功能足够好(它们按预期创建、获取和删除记录)。但是他们在这个过程中不断地抛出一个错误:

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

我的代码不能太差,否则为什么它运行得这么好?尽管如此,我还是想摆脱这个烦人的错误,或者至少理解它。为什么会出现这个错误?


详情:

我的 api 是从 aws-sample“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

遗憾的是,该样本并没有真正使用放大生成的查询和突变。相反,它在文件中使用手写模式:src/graphql.js。这是正确的。生成的查询/突变包含在项目中,但并未实际使用。这对我来说超级失望。但是,当我设法重写 javascript 逻辑以使其(或多或少)使用由 amplify 生成的查询和突变发挥作用时,我的信念(在某种程度上)恢复了。

无论如何,我采取的第一步是编写逻辑,用于 (1) 查询 users 表以查看当前授权用户是否已存在记录,以及 (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 项目的模式。如果不进行编辑,这些查询难道不应该运行良好吗?

【问题讨论】:

【参考方案1】:

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

我在 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设为非空值,因为没有作者就无法发布消息。

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

【讨论】:

以上是关于由 amplify 生成的 Graphql 查询运行良好,但由于身份验证规则而引发错误。为啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Amplify 为 GraphQL API (AWS AppSync) 生成类

AWS Amplify 未生成正确的 graphql 输入深度

@connection 上的 AWS Amplify Graphql 查询

AWS Amplify (GraphQL) - 使用“graphqlOperation”与普通查询?

带有 AWS Amplify 的 GraphQL - 如何启用对查询的排序

AWS Amplify CLI 生成的 GraphQL 突变中的 $condition 输入参数是啥?