В прошлый раз мы сделали простой запрос на получение списка репозиториев пользователя. Там был только код и ни чего лишнего. В этот раз попытаемся разобраться с внутренней схемой устройства ГрафКьюЭль
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»
На этом всё! Спасибо за внимание! Если Вам нужен более простой пример работающего кода, Вы можете найти его здесь