GraphQL с решателями DynamoDB - решение отношений один ко многим - PullRequest
1 голос
/ 20 января 2020

Я прохожу крутой этап обучения, изучая дизайн DynamoDB и применяя его на практике с использованием GraphQL. С первого взгляда я столкнулся с тривиальной проблемой, но позвольте мне остановиться подробнее.

Это простая взаимосвязь между вопросами и ответами, один вопрос может иметь несколько ответов, что дает нам классический c пример отношение ко многим.

У меня есть схема 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 выглядит следующим образом:

enter image description here

Где:

  • Первый столбец: ID
  • Второй столбец: RecordType
  • Третий столбец: значение

У меня также есть два преобразователя: Решатель ответов

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);
            }
        }
    },

Давайте сосредоточимся на решении вопросов. Как видите, он выбирает вопрос по идентификатору, а затем получает ответы на вопрос, объединяет их и возвращает. Также очевидно, что когда вы смотрите на оба средства разрешения проблем, то средство разрешения вопросов использует тот же фрагмент кода, что и средство разрешения ответов.

Вопрос номер один

Как я могу повторно использовать код между распознавателями, чтобы вместо того, чтобы писать один и тот же код дважды, я просто импортировал распознаватель ответов в распознаватель вопросов и выполнял запрос к БД. Должен ли я просто извлечь db logi c в отдельный компонент, повторно использовать компонент и оставить разделители разделителями?

Вопрос номер два

Конструкция DynamoDB, показанная в таблице выше, позволяет запрашивать Вопросы со всеми ответами в одном go, запрашивая записи БД по идентификатору. Если я сделаю запрос на все записи с ID=QUE_1, я также получу все ответы. Проблема здесь в том, что мне нужно было бы сделать довольно обширное отображение / сокращение на стороне javascript, чтобы создать модель данных, как ожидает схема GraphQL. Эффективен ли этот подход? Мне кажется, лучше запросить DynamoDB дважды, чем написать менее упоминаемый код.

...