Как бы вы сопоставили значения полей из разных таблиц с идентификаторами из API? - PullRequest
2 голосов
/ 26 мая 2020

Я знаю, что название может не говорить само за себя, поэтому я постараюсь изложить свою проблему c как можно яснее.

У меня есть приложение NodeJS, которое нужно регулярно публиковать его содержимое во внешний API. Этот контент хранится в базе данных MySQL и разбросан по нескольким таблицам. Итак, допустим, у нас есть две таблицы (с гораздо большим количеством строк, чем это, очевидно, но вы уловили мой дрейф):

Table A:
+-------+---------+---------+---------+
|  id   | field_1 | field_2 | field_3 |
+-------+---------+---------+---------+
| uuid1 | value1  | value2  | value3  |
+-------+---------+---------+---------+

Table B:
+-------+-------------------+---------+---------+
|  id   |  id_field_A (FK)  | field_4 | field_5 |
+-------+-------------------+---------+---------+
| uuid3 |  uuid1            | value4  | value5  |
+-------+-------------------+---------+---------+

и для каждой строки таблицы A, соединенной с таблицей, BI должен опубликовать объект, который DTO будет выглядеть так:

{
    "title": "value3",
    "attributes: {
        "10": "value1",
        "9": "value2",
        "1": "value4",
        "16": "value5" 
    }    
}

Таким образом, каждый идентификатор («1», «9», «10», «16» в примере) используется как ключ в объекте attributes и его значение должно соответствовать значению одного из наших полей из таблиц A или B.

Внешние идентификаторы API («1», «9», «10», «16») не должны различаться между разными среды, поэтому моя идея состояла в том, чтобы создать новую таблицу для сопоставления этих идентификаторов с именами таблиц и полей и получать эти данные из нашей базы данных в любое время, когда нам нужно опубликовать или обновить данные в API. Примерно так:

Table api_attribute:
+-------+-----------------+------------+-----------------+
|  id   |   table_name    | field_name | id_external_api |
+-------+-----------------+------------+-----------------+
| uuid4 |  Table A        | field_1    | "10"            |
+-------+-----------------+------------+-----------------+
| uuid5 |  Table A        | field_2    | "9"             |
+-------+-----------------+------------+-----------------+
| uuid6 |  Table B        | field_4    | "1"             |
+-------+-----------------+------------+-----------------+
| uuid7 |  Table B        | field_5    | "16"            |
+-------+-----------------+------------+-----------------+

Я новичок в разработке игр, поэтому я не уверен, будет ли это рекомендуемым решением, а если нет, я просто изо всех сил пытаюсь найти какие-либо статьи о такого рода тема, поэтому я полагаю, что здесь не хватает некоторых ключевых слов для этой конкретной проблемы ...

Изменить: теперь, когда я написал все это, я понимаю, что это может быть немного излишним и Мне просто нужно сопоставить все эти поля в виде простого javascript, поскольку идентификатор в любом случае не может быть определен программно. Возможно, мне следует использовать простой класс для создания DTO и использовать его в моей службе api следующим образом:

>>>>>>>>>> apiDTO.class.js
class ApiDTO {
    constructor({field_1: value1, field_2: value2, ..., field_5: value5}) {
        this.title: value3;
        this.attributes = {
            "10": value1,
            "9": value2,
            "1": value4,
            "16": value5 
        };
    }
}
module.exports = ApiDTO ;

>>>>>>>> api.service.js
const ApiDTO = require('./apiDTO.class');

module.exports.createAnApiEntity = async () => {
    const allDataToSendToApi = await dataFromDService.getAllFromTableAJoinTableB();
    for (dataToSend of allDataToSendToApi) {
        const apiDto = new ApiDto(dataToSend);
        sendToApi(apiDto);
    }
}

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

1 Ответ

1 голос
/ 26 мая 2020

Предполагая, что dataToSend всегда является плоским объектом, вы можете поместить определение DTO во второй фрагмент в файл (например, dtoTemplate.json) в точном формате JSON, который у вас есть. Этот файл может быть прочитан вашим кодом во время выполнения (вы можете использовать этот ответ или, возможно, один из асинхронных c методов, обсуждаемых в связанном вопросе), и вы можете динамически сопоставить значения в своем шаблоне JSON файл с ключами в dataToSend.

Простая реализация может быть:

function convertToApiDTO(dataToSend) {
  const fs = require('fs');
  const templateJson = fs.readFileSync('path/to/dtoTemplate.json', 'utf8');
  return JSON.parse(
    templateJson,
    (dtoKey, dbKeyOrValue) => dbKeyOrValue in dataToSend ?
      dataToSend[dbKeyOrValue] :
      dbKeyOrValue
  );
}

Я предлагаю добавить дополнительную обработку ошибок, поскольку наличие недопустимого JSON в вашем файле может нарушить эту функцию. Кроме того, если ваш JSON файл может быть отредактирован ненадежными третьими сторонами, он также может быть опасен из-за уязвимости отравления прототипа .

Обратите внимание, что если dbKeyOrValue не является ключом в dataToSend, эта функция устанавливает dbKeyOrValue как постоянное значение с ключом dtoKey в объекте результата. Если вы предпочитаете пропустить эти поля, вы можете вернуть undefined вместо dbKeyOrValue.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...