通过放大生成的Graphql查询工作正常,但由于身份验证规则而引发错误。为什么?

时间:2019-02-28 14:14:34

标签: javascript vuejs2 amazon-dynamodb graphql aws-amplify

摘要: 我正在使用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逻辑以使其(或多或少)起作用时,我的信念得到了恢复(某种程度上)。

无论如何,我要做的第一步是编写逻辑,以用于(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. 如屏幕截图所示,如果我删除了询问用户消息的部分,则放大将生成的getUser查询将起作用。

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

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

因此,我可以通过摆弄数据模型中的连接规范来摆脱错误。

但是等等。这些是通过简单地通过放大来提供的默认查询,只需将其提供给aws-sample项目即可。如果不编辑这些查询,这些查询是否应能正常工作?

Garphql Schema Working Query Failing Query

1 个答案:

答案 0 :(得分: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设置为非null值,因为没有作者就无法发布消息。

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
}