Почему я могу обойти нумерацию страниц, когда я дважды вызываю одно и то же поле (с разными запросами) в GraphQL API GitHub - PullRequest
0 голосов
/ 28 сентября 2019

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

Когда я использую следующий запрос, меня просят выполнить нумерацию страниц (как и ожидалось) -

query {
  user(login:"armsp"){
    repositories{
      nodes{
        name
        issues(states: OPEN){
          totalCount
        }
      }
    }    
  }
}

Сообщение об ошибке после выполнения вышеуказанного -

{
  "data": {
    "user": null
  },
  "errors": [
    {
      "type": "MISSING_PAGINATION_BOUNDARIES",
      "path": [
        "user",
        "repositories"
      ],
      "locations": [
        {
          "line": 54,
          "column": 5
        }
      ],
      "message": "You must provide a `first` or `last` value to properly paginate the `repositories` connection."
    }
  ]
}

Однакокогда я делаю следующее, я на самом деле получаю все результаты, которые не имеют никакого смысла для меня -

query {
  user(login:"armsp"){
    repositories{
      totalCount
    }
    repositories{
      nodes{
        name
        issues(states: OPEN){
          totalCount
        }
      }
    }   
  }
}

Разве меня не спрашивают о нумерации страниц во втором запросе?

1 Ответ

0 голосов
/ 28 сентября 2019

TLDR;Это похоже на ошибку.Невозможно обойти ограничение, применяемое при получении списка ресурсов.

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

Намерение Github - всегда - ограничивать количество результатов при получении списка ресурсов.Это плохо документировано на стороне GraphQL, но соответствует поведению их REST API :

Запросы, которые возвращают несколько элементов, будут разбиты на страницы по 30 элементов по умолчанию.Вы можете указать другие страницы с помощью параметра ?page.Для некоторых ресурсов вы также можете установить пользовательский размер страницы до 100 с параметром ?per_page.

Для соединений похоже, что проверка для параметра first или lastзапускается только тогда, когда в наборе выбора присутствует поле nodes.Это имеет смысл, поскольку в конечном итоге это поле, которое мы хотим ограничить - запрос других полей, таких как totalDiskUsage или totalDiskUsage, даже без аргумента предела, безвреден с точки зрения вышеуказанных проблем.

Вещистаньте фанки, когда вы рассмотрите , как GraphQL обрабатывает наборы выбора с выборками, которые имеют одинаковое имя .Не вдаваясь в подробности, GraphQL позволит вам запрашивать одно и то же поле несколько раз.Если у рассматриваемого поля есть набор выбора, оно эффективно объединит наборы выбора в один.Таким образом,

query {
  user(login:"armsp") {
    repositories {
      totalCount
    }
    repositories {
      totalDiskUsage
    }
  }
}

становится и эквивалентно

query {
  user(login:"armsp") {
    repositories {
      totalCount
      totalDiskUsage
    }
  }
}

. Примечание. Вышеприведенное не сохраняется, если вы явно задаете псевдоним для одного из полей, так кактогда два поля имеют разные имена ответов.

Все это говорит, технически этот запрос:

query {
  user(login:"armsp"){
    repositories{
      totalCount
    }
    repositories{
      nodes{
        name
        issues(states: OPEN){
          totalCount
        }
      }
    }   
  }
}

также должен взорваться с той же MISSING_PAGINATION_BOUNDARIES ошибкой ,Тот факт, что это не означает слияние набора выборок, каким-то образом мешает проверке на месте.Это явно ошибка.Однако, даже если это «работает», оно все равно не преодолеет ограничения, которые Github применяет на уровне хранилища - вы всегда получите максимум 100 результатов даже при использовании вышеуказанной ошибки.

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