Как стать автором
Обновить

GraphQL запрос на GitHub

Время на прочтение3 мин
Количество просмотров4K

В прошлый раз мы сделали простой запрос на получение списка репозиториев пользователя. Там был только код и ни чего лишнего. В этот раз попытаемся разобраться с внутренней схемой устройства ГрафКьюЭль

GraphQL –можно понимать как язык для работы с API или как интерфейс связи. Официальную документацию вы можете найти тут: https://graphql.org/learn/ либо тут: http://spec.graphql.org/June2018/#sec-Overview. ГрафКьюЭль - это уже четвёртая попытка GitHub сделать лучший API для своих пользователей (предъидущей был REST API).

Если вы уже знакомы с токенами и основными принципами работы API, то введение в терминологию по GraphQL Вы можете прочитать здесь: https://docs.github.com/en/graphql/guides/introduction-to-graphql . Если нет – могу порекомендовать прочитать короткую статью с учебным примером. А в данном материале мы более подробно рассмотрим простейшие операции и постараемся разобраться с общей структурой.

Запросы GraphQL отправляются только в формате JSON (больше нет, как такового, метода get, можно только запостить гет-запрос) и возвращают только данные, запрашиваемые в явном виде и только из места, явно указанного в запросе. Это означает, что информация передаются только в виде скаляров (данные, принадлежащие к типам Int, Float, Boolean, String, ID и т.п.) и только если указан полный путь к полю, содержащему нужную информацию. Если вы попытаетесь вернуть поле, которое не является скаляром, проверка схемы выдаст ошибку. Вы должны добавлять вложенные подполя, пока все поля не вернут скаляры.

«GET-запрос»

Типичный запрос на GitHub будет выглядеть примерно так:

'query' : '{'
  'repository(owner:"octocat", name:"Hello-World") {'
    'issues(last:20, states:CLOSED) {'
      'edges {'
        'node {title, url}'
      '}'
    '}'
  '}'
'}'

(pycharm сам расставляет мне кавычки для каждой строки, т.к. реально запрос находится внутри словаря)

Данный запрос выполняет поиск в репозитории octocat/Hello-World, находит 20 последних закрытых проблем и возвращает название каждой проблемы и её URL-адрес

Разберём запрос построчно:

query : {

Операция объявления переменной чтения данных

repository(owner:"octocat", name:"Hello-World") {

Обращение к Объекту репозитория, с указанием владельца и имени.

issues(last:20, states:CLOSED) {

Запрашиваем двадцать последних проблем в статусе «Закрыто» (Чтобы запросить конкретную проблему, пришлось бы указать её порядковый номер в качестве аргумента).

edges {

Вообще Поле issues позволяет запрашивать несколько связанных объектов в рамках одного вызова. Чтобы получить данные об отдельных проблемах, мы должны получить доступ к узлу через edges. У каждого под-Поля edges есть под-под-Поля node и cursor.

node {

Содержит конечный узел. Именно в этом узле, согласно документации, находится информация об искомой ошибке. Курсор в данном примере не представлен в явном виде, но вообще используется для нумерации страниц (https://graphql.org/learn/pagination/ )

title, url}

Наконец прочитав документацию (https://docs.github.com/en/graphql/reference/objects#issue) мы можем указать, какие именно Поля хотим получить. Здесь мы запрашиваем title и url, объекта Issue.

Вот примерный текст ответа:

{"data":{"repository":{"issues":{"edges":[{"node":
{"title":"title","url":"https://github.com/octocat/Hello-World/issues/987"}},
{"node":{"title":"title","url":"https://github.com/octocat/Hello-World/issues/988"}},
{"node":{"title":"123","url":"https://github.com/octocat/Hello-World/issues/993"}},
{"node":{"title":"Hello, world!","url":"https://github.com/octocat/Hello-World/issues/994"}},
{"node":{"title":"Jddjfjfnfn","url":"https://github.com/octocat/Hello-World/issues/1009"}}]}}}}

Мы можем видеть путь, вплоть до узла-окрестности, содержащей интересующую нас информацию ("data":"repository":"issues":"edges"), а так же размещённые там поля title и url.

Что бы получить структурированный список, пройдёмся по ответу циклом:

issuen = data['data']['repository']['issues']['edges']
for issu in issuen:
    print(issu['node']['title'], '-' ,issu['node']['url'])

Получим аккуратный список вида «Название ошибки – URL»

На этом всё! Спасибо за внимание! Если Вам нужен более простой пример работающего кода, Вы можете найти его здесь

Теги:
Хабы:
Всего голосов 8: ↑4 и ↓40
Комментарии0

Публикации