首页 > 解决方案 > 带有 DynamoDB 解析器的 GraphQL - 一对多关系解决方案

问题描述

我正在经历学习 DynamoDB 设计并使用 GraphQL 在实践中应用它的陡峭学习曲线。乍一看,我遇到了一个微不足道的问题,但让我详细说明一下。

这是问题和答案之间的简单关系,一个问题可以有多个答案,这为我们提供了一对多关系的经典示例。

我有一个 GraphQL 模式,它看起来像这样:(为了保持简单,省略了不必要的位)

问题架构

    extend type Query {
        question (ID: ID!): Question
    }

    type Question {
        ID: ID!
        RecordType: String!
        value: String!
        answers: [Answer!]
    }

答案架构

    extend type Query {
        answers(QUE_ID: ID!): [Answer!]
    }

    type Answer {
        ID: ID!
        RecordType: String!
        value: String!
    }

DynamoDB 的设计是这样的:

在此处输入图像描述

在哪里:

我也有两个解析器: 答案解析器

Query: {
        answers: async (parent, { QUE_ID }, { dataSources }) => {
            try {
                const args = {
                    KeyConditionExpression: "ID=:id and begins_with(RecordType, :rtype)",
                    ExpressionAttributeValues: {
                        ":id": QUE_ID,
                        ":rtype": "AR_ANS"
                    }
                };

                return await dataSources.questoSource.query(args);
            } catch (err) {
                console.log(err);
            }
        }
    }

问题解决者

Query: {
        question: async (parent, { ID }, { dataSources }) => {
            try {
                // get question from the db
                const question = await dataSources.questoSource.getRecord({
                    ID,
                    RecordType: `${process.env.QUESTION_PREFIX}`
                });

                // get question's answers from the db
                const args = {
                    KeyConditionExpression: "ID=:id and begins_with(RecordType, :rtype)",
                    ExpressionAttributeValues: {
                        ":id": ID,
                        ":rtype": "AR_ANS"
                    }
                };

                const answers = await dataSources.questoSource.query(args);

                // combine answers with the question from the first db query
                question.answers = answers.Items;

                // return the result
                return question;
            } catch (err) {
                console.log(err);
            }
        }
    },

让我们专注于问题解决者。如您所见,它通过 ID 获取问题,然后获取问题的答案,将它们组合并返回。同样显而易见的是,当您查看两个解析器时,问题解析器使用与答案解析器完全相同的代码。

问题一

我怎样才能在解析器之间重用代码,而不是两次编写相同的代码,我只需将答案解析器导入问题解析器并运行数据库查询。我是否应该将数据库逻辑提取到一个单独的组件并重用该组件并使解析器分开?

问题二

上表中显示的 DynamoDB 设计允许通过按 ID 查询数据库记录来一次性查询问题及其所有答案。如果我查询所有记录,ID=QUE_1我也会得到所有答案。这里的问题是我必须在 javascript 端做一些相当广泛的映射/减少,以使数据模型符合 GraphQL 模式的预期。 这种方法有效吗?在我看来,最好查询 DynamoDB 两次,而不是编写较少提及的代码。

标签: javascriptgraphqlamazon-dynamodbgraphql-js

解决方案


推荐阅读