Запрос GraphQL принимает несколько списков в качестве аргументов

Речь идет о добавлении GraphQL к существующему API Java, который принимает несколько списков в качестве входных данных.

Фон:

У меня есть REST API на основе Java getFooInformationByRecognizer, который принимает список распознавателей, где каждый объект распознавателя содержит идентификатор и его тип, и возвращает информацию, соответствующую каждому идентификатору. Возможны только 3 типа: A, B или C. Ввод может быть любой комбинацией этих типов.

Например:

[{"id": "1", "type": "A" }, {"id": "2", "type": "B"},{"id": "3", "type": "C"}, {"id": "4", "type": "A"}, {"id":"5", "type": "B"}]

Вот его представление Java:

class FooRecognizer{
     String id;
     String FooType;
}

Этот API выполняет небольшую обработку. Сначала извлекается весь ввод с идентификаторами типа A и извлекается информация, соответствующая этим идентификаторам. Аналогичным образом извлеките идентификаторы типа B и извлеките информацию, соответствующую этим идентификаторам, и аналогично для C. Итак, он извлекает данные из 3 разных источников и, наконец, сопоставляет их с одной картой и возвращает. Например:

ids of type A --> A SERVICE -> <DATA SOURCE FOR A>
ids of type B --> B SERVICE --> <DATA SOURCE FOR B>
ids of type C --> C SERVICE --> <DATA SOURCE FOR C>

Наконец делает это: Информация A + информация B + информация C и помещает это в хэш-карту Java.

Java-представление запроса к этой службе:

class FooRequest{
   private Bar bar;
   List<FooRecognizer> list;
}

Java-представление объекта ответа от службы:

class FooInformationResponse{
   private Map<String, FooRecognizer> fooInformationCollated;
}

Пример вывода JSON ответа:

 "output":{
    "fooInformationCollated":{
    "1":{
       "someProperty": "somePropertyValue"
       "listOfNestedProperties": [{"x": "xValue", "y": "yValue", "z","zValue"]
       "nestedProperty":{
          "anotherProperty":{
            "furtherNestedProperty": "value"
          }
        }
      }
   "2":{
        "someProperty": "somePropertyValue"
        "listOfNestedProperties": [{"a": "aValue", "b": "bValue", "c","cValue"]
        "nestedProperty":{
           "anotherProperty":{
             "furtherNestedProperty": "value"
          }
        }
      }
    }... and so on for other ids in the input

Теперь я хочу преобразовать этот сервис в GraphQL, и вот мой запрос.

query{
  getFooInformationByRecognizer(filterBy:{
    fooRecognizer: [{
            id: "1",
            fooType: A
        }],
        bar: {
            barId: "someId",
            ...<other bar info>
        }
  }){
    fooInformationCollated{
      id
      fooInformation{
        someProperty
        listOfNestedProperties
        nestedProperty{
         anotherProperty{
            furtherNestedProperty
          }
        }

      }
    }
  }
}

Вот моя схема GraphQL:

type Query{
    getFooInfoByRecognizer (filterBy: getFooByRecognizerTypeFilter!):getFooByRecognizerTypeFilterResponse
}

input getFooByIdentifierTypeFilter{
    bar: Bar!
    fooIdentifiers: [FooIdentifier!]!
}

input Bar{
    barId: String!
    ....
}


input FooIdentifier{
    id: String!
    fooIdType: fooIdtype!
}

enum fooIdType{
    A
    B
    C
}

У меня есть несколько вопросов:

  1. Будет ли это лучшим способом/лучшей практикой для представления этого запроса? Или я должен смоделировать свой запрос, чтобы иметь возможность принимать 3 отдельных списка. Например: query getFooInformationByRecognizer(barId, listOfAs, listOfBs, listOfCs). Любой другой выбор, который у меня есть для запроса/модели?
  2. Я нашел сложный тип ввода как самый простой. В общем, есть ли какая-то конкретная причина для выбора сложного типа ввода вместо других вариантов или наоборот?
  3. Есть ли что-то, связанное с производительностью запросов, о которой я должен беспокоиться? Я пытался изучить DataLoader/BatchLoading, но это не совсем подходит. Я не думаю, что проблема N+1 должна быть проблемой, так как я также создам отдельные отдельные преобразователи для A, B и C, но запрос, как видно, не делает дальнейших вызовов серверной части, как только JSON возвращается в ответ.
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вопрос слишком широк, чтобы ответить конкретно, но вот моя лучшая попытка.

  1. Хотя однозначного ответа на вопрос об одном сложном входном аргументе по сравнению с несколькими более простыми аргументами не существует, один сложный аргумент, как правило, предпочтительнее, поскольку клиентам проще передавать одну переменную, а файлы GraphQL меньше. Это может быть более интересно для мутаций, но в любом случае это хорошая эвристика. См. логику, объясняющую это более подробно, например. в этой статье.

  2. Логика, описанная выше, перекликается с вашими собственными наблюдениями.

  3. Для этого конкретного сценария, который вы перечислили, я не вижу ничего важного для производительности. Кажется, вы получаете весь список за один раз (без N + 1), поэтому мало чем отличается от того, что вы делаете для своей конечной точки REST. Теперь я не могу сказать, насколько дорого обходится получение полей более низкого уровня (например, нужны ли вам JOIN или сетевые вызовы или что-то еще), но если есть какая-то нетривиальная логика, вы можете оптимизировать ее, глядя вперед в подвыбор перед разрешением ваших полей верхнего уровня.

Другие вопросы по теме