Как установить graphql на windows

Обновлено: 05.07.2024

Мы составили гайд по GraphQL для начинающих. GraphQL — это язык запросов с открытым исходным кодом, создавался как более эффективная альтернатива REST для разработки и использования программных интерфейсов приложений.

Создание и развёртывание REST API с помощью Go, PostgreSQL, JWT и GORM

GraphQL обладает множеством достоинств, например:

  1. Вы получаете информацию именно в том объёме, в котором запрашиваете..
  2. Вам будет необходима всего одна конечная точка.
  3. GraphQL — сильно типизированный язык, что позволяет предварительно оценить корректность запроса в рамках системы типов синтаксиса.

С чего начать?

Чтобы понять, как применять стандарт на практике, используем сервер в базовой конфигурации — Graphpack.

Нужно создать новую папку для проекта. В данном случае имя папки будет graphql-server , однако название не принципиально. Откройте терминал и введите:

На компьютере должен быть установлен npm или yarn. Перейдите в созданную папку и введите команду в зависимости от используемого менеджера:

npm создаст файл package.json , в котором будут храниться все созданные вами зависимости и команды. Теперь нужно установить одну зависимость, которую мы будем использовать в рамках этой статьи.

Graphpack позволяет создать сервер GraphQL с базовой конфигурацией. Используя терминал, в корневой папке проекта установите Graphpack с помощью команды:

Если вы используете yarn:

Перейдите к файлу package.json и добавьте следующий код:

Создайте на сервере папку src . В этом примере это будет единственная папка на сервере, в которой необходимо создать три файла. В src создайте файл schema.graphql . В файл добавьте код:

В этом файле будет находиться вся схема GraphQL.

Sportmaster Lab , Санкт-Петербург, Москва, Краснодар, можно удалённо , От 100 000 до 350 000 ₽

Создайте второй файл в той же папке, назовите его resolvers.js . Разместите там следующий код:

В этом файле будут размещены инструкции по выполнению операций GraphQL.

Создайте третий файл, db.js , содержащий код:

Для тестирования работы GraphQL начинающим специалистам нет нужды использовать настоящие данные. Этот файл нужен для симуляции обращений к базе данных.

После выполнения операций папка src должна выглядеть следующим образом:

GraphQL tutorial

Теперь выполните команду npm run dev для npm или yarn dev для yarn. Терминал должен вывести информацию об успешном запуске сервера:

Теперь можно перейти к localhost:4000 . Система готова к работе над GraphQL API. Для разработки используется IDE GraphQL Playground.

Схема

GraphQL прост для начинающих благодаря собственному языку — Schema Definition Language (SDL). SDL обладает интуитивно понятным синтаксисом и универсален для любой используемой технологии.

Типы — одна из основных особенностей языка запросов GraphQL. Это кастомные объекты, которые определяют, как будет выглядеть GraphQL API. Например, при разработке программного интерфейса для приложения, взаимодействующего с соцсетями, в API стоит объявить типы Posts , Users , Likes , Groups .

В типах есть поля, возвращающие определённые разновидности данных. Например, при создании типа User, в него стоит включить поля name , email , и age . Поля типов могут быть любыми и всегда возвращают данные в формате Int, Float, String, Boolean, ID, List of Object Types, или Custom Objects Types.

Чтобы создать первый тип, откройте файл schema.graphql и замените ранее прописанный там тип Query следующим кодом:

Каждая запись типа User должна иметь идентификационный номер, поэтому поле id содержит данные соответствующего типа. Поля name и email содержат String (переменную типа строки символов), а age — целочисленную переменную.

Восклицательный знак в конце определения поля означает, что это поле не может быть пустым. Единственное поле без восклицательного знака — age .

Язык запросов GraphQL оперирует тремя основными концепциями:

  1. queries, запросы — с их помощью получают данные с сервера.
  2. mutations, изменения — модификация данных на сервере и их обновление.
  3. subscriptions , подписки — методы поддержания постоянной связи с сервером.

Запросы

Откройте файл schema.graphql и добавьте тип Query :

Запрос users будет возвращать массив из одной и более записей типа User . Поскольку в определении использованы восклицательные знаки, ответ на запрос не может быть пустым.

Для получения конкретной записи User необходимо создать соответствующий запрос. В данном случает это будет запрос user в типе Query . Добавьте в код следующую строку:

Теперь код должен выглядеть так:

Как видите, в запросах GraphQL можно передавать аргументы. В данном случае для получения конкретной записи в запросе в качестве аргумента используется её поле id .

Местонахождение данных, которые будут обрабатываться в соответствии с запросом, определяется в файле resolvers.js . Откройте этот файл и импортируйте учебную базу данных db.js :

Затем замените функцию hello на user и users :

В каждом резолвере запроса есть четыре аргумента. В запросе user в качестве аргумента передаётся содержимое поля id записи базы данных. Сервер возвращает содержимое подходящей записи. Запрос users не содержит аргументов и всегда возвращает весь массив целиком.

Для тестирования получившегося кода перейдите к localhost:4000 .

Следующий код должен вернуть список всех записей db.js :

Получить первую запись из базы можно с помощью этого кода:

Изменения

В GraphQL изменения — способ модифицировать данные на сервере и получить обработанную информацию. Этот процесс можно рассматривать как аналогичный концепции CUD (Create, Update, Delete) в стандарте REST.

Для создания изменения откройте файл schema.graphql и добавьте новый тип mutation :

В данном случае указано три различных изменения:

  • createUser : необходимо передать значение полей id , name , email и age . Функция возвращает запись типа User .
  • updateUser : необходимо передать значение поля id , новое значение поля name , email или age . Функция возвращает запись типа User .
  • deleteUser : необходимо передать значение поля id . Функция возвращает запись типа User .

Теперь откройте файл resolvers.js и ниже объекта Query создайте новый объект mutation :

Полный код файла resolvers.js должен выглядеть так:

Сделайте запрос к localhost:4000 :

Он должен вернуть новую запись типа User . Опробуйте также остальные функции изменения.

Подписки

Несмотря на то что этот код выглядит похожим на запрос, работает он несколько иначе. При обновлении данных сервер выполняет определённый в подписке запрос GraphQL и рассылает обновлённые данные клиентам.

Заключение

GarphQL набирает популярность. В рамках опроса State of JavaScript, проведённого среди JS-разработчиков, более половины респондентов указали, что слышали об этой технологии и хотели бы с ней ознакомиться, а пятая часть уже её использует и не намерена отказываться.

Надеемся, что наше руководство по GraphQL для начинающих окажется полезным и заинтересует в дальнейшем изучении.

image

В последнее время я все чаще и чаще слышу про GraphQL. И в интернете уже можно найти немало статей о том как сделать свой GraphQL сервер. Но почти во всех этих статьях в качестве бэкенда используется Node.js.

Я ничего не имею против Node.js и сам с удовольствием использую его, но все-таки большую часть проектов я делаю на PHP. К тому же хостинг с PHP и MySQL гораздо дешевле и доступнее чем хостинг с Node.js. Поэтому мне кажется не справедливым тот факт, что об использовании GraphQL на PHP в интернете практически нет ни слова.

В данной статье я хочу рассказать о том, как сделать свой GraphQL сервер на PHP с помощью библиотеки graphql-php и как с его помощью реализовать простое API для получения данных из MySQL.

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

Подготовка

В данной статье я не буду делать фронтенд, поэтому для удобного тестирования запросов к GraphQL серверу рекомендую установить GraphiQL-расширение для браузера.

Для Chrome это могут быть:

В таблице «users» будем хранить список пользователей:

Таблица users

А в таблице «friendships» связи типа «многие-ко-многим», которые будут обозначать дружбу между пользователями:

Таблица friendships

Дамп базы данных, как и весь остальной код, можно взять из репозитория данной статьи на Github.

Hello, GraphQL!

Для начала необходимо установить graphql-php в наш проект. Можно сделать это с помощью composer:


Теперь, по традиции напишем «Hello, World».

Для этого в корне создадим файл graphql.php, который будет служить конечной точкой (endpoint) нашего GraphQL сервера.

В нем подключим автозагрузчик composer:


Чтобы заставить GraphQL выполнить запрос необходимо передать ему сам запрос и схему данных.

Для получения запроса напишем следующий код:


Чтобы создать схему сначала подключим GraphQL\Schema:


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

Также схема может содержать необязательный корневой тип данных Mutation, который предоставляет API для записи данных, но в рамках данной статьи мы его рассматривать не будем.

В простейшем случае тип данных Query должен быть экземпляром класса ObjectType, а его поля должны быть простых типов (например int или string), поэтому подключим классы предоставляющие эти типы данных в GraphQL:


И создадим тип данных Query:


Как можно заметить тип данных обязательно должен содержать имя (name) и массив полей (fields), а также можно указать необязательное описание (description).

Также тип данных может содержать свойства «interfaces», «isTypeOf» и «resolveField», но в рамках данной статьи мы их рассматривать не будем.

Поля типа данных также должны иметь обязательные свойства «name» и «type». Если свойство «name» не задано, то в качестве имени используется ключ поля (в данном случае «hello»). Также в нашем примере у поля «hello» заданы необязательные свойства «description» — описание и «resolve» — функция возвращающая результат. В этом случае функция «resolve» просто возвращает строку "Привет, GraphQL!", но в более сложной ситуации она может получать какую-либо информацию по API или из БД и обрабатывать ее.

Также поля могут содержать свойство args, которое будет рассмотрено в статье позже, и свойство deprecationReason, которое в данной статье не рассматривается.

Таким образом, мы создали корневой тип данных «Query», который содержит всего одно поле «hello», возвращающее простую строку текста. Давайте добавим его в схему данных:


А затем выполним запрос GraphQL для получения результата:


Остается только вывести результат в виде JSON и наше приложение готово:


Обернем код в блок try-catch, для обработки ошибок и в итоге код файла graphql.php будет выглядеть так:

Проверим работу GraphQL. Для этого запустим расширение для GraphiQL, установим endpoint (в моем случае это «localhost/graphql.php») и выполним запрос:

Проверка работы GraphQL

Вывод пользователей из БД

Теперь усложним задачу. Выведем список пользователей из базы данных MySQL.

Для этого нам понадобится создать еще один тип данных класса ObjectType. Чтобы не нагромождать код в graphql.php, вынесем все типы данных в отдельные файлы. А чтобы у нас была возможность использовать типы данных внутри самих себя, оформим их в виде классов. Например, чтобы в типе данных «user» можно было добавить поле «friends», которое будет являться массивом пользователей такого же типа «user».

Когда мы оформляем тип данных в виде класса, то не обязательно указывать у него свойство «name», потому что оно по умолчанию берется из названия класса (например у класса QueryType будет имя Query).

Теперь корневой тип данных Query, который был в graphql.php:


Будет находиться в отдельном файле QueryType.php и выглядеть так:


А чтобы в дальнейшем избежать бесконечной рекурсии при определении типов, в свойстве «fields» лучше всегда указывать не массив полей, а анонимную функцию, возвращающую массив полей:


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

Также в папке App создадим подпапку Type, в которой будем хранить все наши типы данных и перенесем в нее QueryType.php.

Теперь добавим пространство имен и заполним реестр Types.php необходимыми типами:

Пока в нашем реестре будет всего 2 типа данных: 1 простой (string) и 1 составной (query).

Теперь во всех остальных файлах вместо:


Подключим наш реестр типов:


И заменим все ранее указанные типы, на типы из реестра.

В QueryType.php вместо:


А схема в graphql.php теперь будет выглядеть так:


Чтобы получить пользователей из базы данных, необходимо обеспечить интерфейс доступа к ней. Получать данные из базы можно любым способом. В каждом фреймворке для этого есть свои инструменты. Для данной статьи я написал простейший интерфейс который может подключаться к MySQL базе данных и выполнять в ней запросы. Так как это не относится к GraphQL, то я не буду объяснять как реализованы методы в данном классе, а просто приведу его код:

В файле graphql.php добавим код для инициализации подключения к БД:


Теперь в папке Type создадим тип данных User, который будет отображать данные о пользователе. Код файла UserType.php будет таким:

Значение полей можно понять из их свойства «description». Свойства «id», «name», «email» и «countFriends» имеют простые типы, а свойство «friends» является списком друзей – таких же пользователей, поэтому имеет тип:


Необходимо также добавить в наш реестр пару базовых типов, которые мы раньше не использовали:


И только, что созданный нами тип User:


Возвращаемые значения (resolve) для свойств «friends» и «countFriends» берутся из базы данных. Анонимная функция в «resolve» первым аргументом получает значение текущего поля ($root), из которого можно узнать id пользователя для вставки его в запрос списка друзей.

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

В завершении изменим код QueryType.php так, чтобы в API были поля для получения информации о конкретном пользователе по его идентификатору (поле «user»), а также для получения списка всех пользователей (поле «allUsers»):

Тут чтобы узнать идентификатор пользователя, данные которого необходимо получить, у поля «user» мы используем свойство «args», в котором содержится массив аргументов. Массив «args» передается в анонимную функцию «resolve» вторым аргументом, используя который мы узнаем id целевого пользователя.

У аргументов могут быть свои свойства, но в этом случае я использую упрощенную форму записи массива аргументов, при которой ключи массива являются именами, а значения – типами аргументов:

Теперь можно запустить сервер GraphQL и проверить его работу таким запросом:

Проверка работы GraphQL: Получение данных пользователя

Проверка работы GraphQL: Получение данных пользователя

Или любым другим.

Заключение

На этом все. Читайте документацию. Задавайте вопросы в комментариях. Критикуйте.

Что такое GraphQL: с основ до первых запросов главное изображение

Прежде чем рассматривать GraphQL, давайте уделим внимание исторической базе. Что такое SQL — structured query language или язык структурированных запросов?

SQL — декларативный язык программирования, который применяется для создания, изменения и управления данными в базах данных. Этот язык поддерживает четыре базовых оператора запросов: SELECT, INSERT, UPDATE и DELETE. С помощью SQL мы можем запросить из базы данных (БД) именно то, что нам необходимо.

Прокачивайте свой уровень программирования: На Хекслете есть несколько десятков треков — специальных курсов для опытных программистов, позволяющие повысить уровень компетентности разработчика в разных направлениях.

Например, когда необходимо «достать» из БД всех пользователей с именем Maria, это можно сделать с помощью запроса:

Решить эту задачу с помощью REST можно несколькими способами:

  1. Определить endpoint на сервере, который будет отдавать из базы данных пользователей с fname Maria.
  2. Определить общий endpoint для получения всех пользователей и фильтровать полученный список на стороне клиента.

При этом в каждом из вариантов есть свои минусы. Первый подход нельзя масштабировать, так как нет возможности создать endpoint для каждого пользователя. Если мы используем второй подход, повышается нагрузка на сеть, а также появляется необходимость в постобработке на стороне клиента.

А теперь представьте инструмент, который объединяет возможности SQL и REST на стороне клиента. Вы уже догадались, что он называется GraphQL. Этот инструмент берёт идеи, разработанные для манипуляции данными в БД, и использует их в вебе. Поэтому с помощью одного запроса GraphQL можно получить сразу все необходимые данные.

Ниже представлена информация, необходимая для начала работы с GraphQL.

Query: запросы в GraphQL

Примечание — Обратите внимание, все типы запросов в GraphQL отправляются через POST.

Query описывает данные, которые необходимо получить с сервера. Например, с помощью кода ниже можно получить fname и age всех пользователей в базе данных.

В ответ на этот запрос сервер присылает данные в формате JSON. Структура ответа соответствует структуре запроса.

Mutation: мутации в GraphQL

Mutation — ещё один root types. С его помощью можно добавлять данные в БД. Mutation — аналог POST и PUT в REST. Ниже пример кода.

Здесь создаётся мутация createUser, которая добавляет в БД пользователя с fname Richie и age 22. В ответ на этот запрос сервер присылает JSON с id записи. Ответ выглядит так:

Subscription: подписки в GraphQL

Subscription — третий тип операций в GraphQL. С его помощью клиент слушает изменения в БД в режиме реального времени. Под капотом подписки используют вебсокеты. Пример кода:

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

Например, когда пользователь с fname Richie получает лайк, ответ будет таким:

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

Выше представлены три основных типа запросов в GraphQL. Несмотря на поверхностное знакомство, вы получили достаточно знаний, чтобы начать работать со схемой GraphQL.

Как работать с сервером GraphQL

Рассмотрим ответ на этот вопрос на конкретном примере.

Цель: настроить сервер GraphQL, который отвечает на три типа запросов к БД NoSQL, в которой есть список пользователей с такой структурой:

Также в базе данных есть списки постов, которые опубликовали пользователи.

Для дальнейшей работы понадобится сервер Apollo. Это сервер GraphQL с открытым исходным кодом.

Настройте проект и установите зависимости:

Вы создали пустой проект. Теперь установите GraphQL, Apollo и nodemon для отслеживания изменений в файлах.

Чтобы nodemon работал, добавьте в package.json запись:

База данных

Данные в этом примере поместим в переменную JSON. В реальных проектах данные обычно хранятся в БД. В тестовом проекте данные хранятся в index.js. Вот они:

Теперь можно перейти к работе с сервером GraphQL.

Схема

Работа с сервером GraphQL всегда начинается с разработки схемы (Schema). Она состоит из двух взаимосвязанных объектов: TypeDefs и Resolvers.

Выше были описаны основные типы GraphQL. Чтобы сервер мог с ними работать, эти типы необходимо определить. Объект typeDef определяет список типов, которые доступны в проекте. Код выглядит так:

В примере выше определяется тип User, в котором указываются fname , age , likes и другие данные. Для каждого поля определяется тип данных: String или Int . GraphQL поддерживает четыре типа данных: String , Int , Float , Boolean . Если в поле указан восклицательный знак, оно становится обязательным.

Также в примере выше определяются типы Query , Mutation и Subscription .

Первый тип, который содержит внутри себя тип Query , называется users . Он принимает id и возвращает объект с данными соответствующего пользователя. Это обязательное поле. Ещё один тип Query называется posts . Он устроен так же, как users .

Тип Mutation называется incrementLike . Он принимает параметр fname и возвращает список пользователей.

Тип Subscription называется listenLikes . Он возвращает список пользователей.

После определения типов необходимо добавить их логику. Это нужно, чтобы сервер знал, как отвечать на запросы клиента. Эта задача решается с помощью Resolvers.

Resolver

Resolver или распознаватель — функция, которая возвращает данные для определённого поля. Resolver’ы возвращают данные того типа, который определён в схеме. Распознаватели могут быть асинхронными. С их помощью можно получать данные из REST API, базы данных или другого источника.

В примере выше есть шесть функций:

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

Итак, работа с типами и распознавателями завершена. Теперь можно запустить сервер.

Потратили 15 минут на настройку сервера и, вуаля, написали первый запрос. Полная версия кода опубликована здесь.


REST vs. GraphQL

Что делать, если нам нужно найти пользователя, который опубликовал пост с id x? Рассмотрим, как эта задача решается с помощью REST. Вот данные:

Сначала необходимо определить endpoint’ы GET:

Когда необходимо получить данные о пользователе, который опубликовал пост с id 1, запрос выглядит так:

Чтобы получить нужные данные, приходится дважды обращаться к серверу.

Что делать, если нужно получить только имя пользователя? Конечно, можно использовать данные поля fname . Но мы уже получили дополнительные данные: id , likes , age . Операция становится слишком дорогой.

Можно попробовать использовать endpoint, который получает только данные из поля fname :

Это решает проблему. Но сложность в том, что вам придётся создавать endpoint для каждого типа информации. Это неудобно.

Давайте посмотрим, как можно решить задачу с помощью GraphQL. Всё, что вам требуется — простой запрос:

Если нужно получить age пользователя, который опубликовал пост с id 1, запрос будет таким:

Поле user в запросе определено в схеме. Поэтому вы можете получать нужную информацию без использования endpoint’ов и повторных обращений к серверу.

Изучайте Node.js на Хекслете Первые курсы в профессии «Node.js-программист» доступны бесплатно. Регистрируйтесь и начинайте учиться.

Заключение

В руководстве рассмотрена базовая информация о GraphQL: краткая теория, типы, отличия от REST. В комментариях можно поделиться впечатлениями о GraphQL и опытом применения этого инструмента.

Адаптированный перевод статьи So, What the Heck is GraphQL by Karthik Kalyanaraman. Мнение автора оригинальной публикации может не совпадать с мнением администрации «Хекслета».

Никогда не останавливайтесь: В программировании говорят, что нужно постоянно учиться даже для того, чтобы просто находиться на месте. Развивайтесь с нами — на Хекслете есть сотни курсов по разработке на разных языках и технологиях.


FastAPI - это высокопроизводительный фреймворк для создания веб-API с помощью Python. Его простой и интуитивно понятный характер позволяет легко и быстро разрабатывать надежные веб-API, используя очень мало шаблонного кода. В этой статье мы расскажем о FastAPI и о том, как настроить с его помощью сервер GraphQL.

Из официальной документации, создания веб - приложений с FastAPI сокращает около 40 процентов индуцированных ошибок разработчика, и это стало возможным благодаря использованию объявлений типа Python 3.6. Благодаря всем его функциям, включая автоматическое создание интерактивной документации API, создание веб-приложений с помощью Python никогда не было таким простым.

Настройка нашего приложения

Прежде чем мы начнем, давайте подтвердим, что у нас установлен Python 3.6+, выполнив следующую команду в терминале:

Если это вернет ошибку, кликните здесь, чтобы загрузить и установить Python на свой локальный компьютер. Установка Python 3.4+ по умолчанию поставляется с pip, однако нам понадобится Python 3.6+, чтобы иметь возможность запускать FastAPI. Pip - это предпочтительный менеджер пакетов Python, который мы будем использовать для установки поддерживающих модулей для нашего приложения FasAPI.

Установив Python и pip, давайте добавим FastAPI на нашу машину, выполнив следующую команду в терминале:

Нам также понадобится Uvicorn, сервер ASGI (интерфейс асинхронного серверного шлюза) для обслуживания нашего приложения. Давайте запустим следующую команду в терминале, чтобы установить его:

После этого мы можем продолжить и создать новый каталог для нашего приложения. Назовем это fastapi-graphql . Внутри нашего нового каталога мы создадим новый файл с именем main.py . Это будет индексный файл для нашего сервера.

Основы GraphQL: запросы и схема

Запросы GraphQL

В GraphQL запросы используются для получения данных, как и запросы GET в архитектуре REST API. Однако с запросами GraphQL у нас есть выбор запрашивать именно то, что мы хотим. Например, предположим, что у нас есть API для образовательных курсов. Запрос к нашему API будет выглядеть так:

Когда мы посылаем этот запрос, мы должны получить ответ с курсами от нашего API и их свойств, в таком порядке: id , title , instructor и publishDate :

При желании мы можем попросить наш API вернуть список курсов, но на этот раз только со свойством title :

Мы должны получить такой ответ:

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

Схема GraphQL

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

Чтобы продемонстрировать это, мы создадим файл schemas.py в нашем корневом каталоге, который мы будем использовать для размещения всех полей данных. Давайте начнем с типа курса. Он должен содержать всю информацию для конкретного курса, и из приведенного выше примера запроса курс включает поля id, title, instructor и publish_date:

В нашем файле schemas.py мы начали с импорта типов String и ObjectType из graphene . Graphene - это библиотека Python для построения схем и типов GraphQL. Давайте запустим следующую команду в терминале, чтобы установить его:

После того, как мы успешно импортировали String и ObjectType из graphene , мы перешли к определению класса CourseType с импортированными ObjectType в скобках. Мы объявим почти все наши типы GraphQL как типы объектов.

Следующее, что мы сделали, это создали разные поля для нашего CourseType , и мы использовали тип String для каждого поля. Некоторые другие типы из graphene включают в себя Int , Enum , Date , List и Boolean .

Обратите внимание, что мы также добавили аргумент required в тип String для id , title и instructor . Это означает, что мы не сможем добавить курс в нашу службу GraphQL без включения этих полей, хотя мы все равно можем исключить любое из них при выполнении запросов.

Настройка временной базы данных

Теперь, когда у нас есть схема, нам также понадобится место для хранения и извлечения данных нашего курса. для этой демонстрации мы будем использовать базу данных JSON. Однако FastAPI поддерживает как реляционные, так и нереляционные базы данных, такие как PostgreSQL, MySQL, MongoDB, ElasticSearch и т.д.

Давайте создадим файл courses.json в нашем корневом каталоге и вставим в него следующий блок кода:

Мы сможем использовать наш GraphQL API для изменения и извлечения данных из этого файла.

Создание наших резолверов запросов

Резолверы - это то, что наша служба GraphQL будет использовать для взаимодействия с нашей схемой и источником данных. Чтобы создать преобразователь запросов для получения курсов, мы начнем с импорта fastapi в наш файл main.py :

Затем давайте импортируем соответствующие типы, которые мы будем использовать в нашем преобразователе запросов, как мы это сделали в файле schemas.py :

Обратите внимание, что мы добавили два новых типа: List который мы будем использовать в качестве оболочки для наших CourseType ; и Schema , который мы будем использовать для выполнения операции.

Мы также импортируем AsyncioExecutor из graphql.execution.executors.asyncio , что позволит нам выполнять асинхронные вызовы в нашем сервисе GraphQL; GraphQLApp из starlette.graphql ; и CourseType из нашего сервиса файл schemas.py :

Наконец, импортируем встроенный пакет json для работы с нашим файлом courses.json :

Наш последний блок импорта должен выглядеть так:

Затем давайте создадим наш запрос, добавив в наш файл main.py следующий блок кода:

В приведенном выше блоке мы начали с создания класса Query на основе типа объекта, а затем инициализировали переменную course_list . Здесь мы будем хранить данные курса.

Поскольку мы будем возвращать различные объекты курса в списке, мы использовали тип List , который мы импортировали из graphene , чтобы обернуть наш CourseType , а затем присвоили его переменной get_course . Это будет имя нашего запроса.

Важно отметить, что при выполнении запроса в клиенте GraphQL нам необходимо указать имя в верблюжьем регистре, то есть getCourse вместо get_course .

Затем мы создали метод resolver в строке 4 для запроса get_course . Имя метода resolver должно начинаться с префикса resolve , за которым следует имя запроса — в данном случае get_course — и затем разделяться символом подчеркивания.

Метод resolver также ожидает два позиционных аргумента, которые мы включили в определение метода. В строках 5-7 мы загружаем данные из нашего файла courses.json , назначаем его course_list , а затем возвращаем переменную.

Запуск нашего сервера GraphQL на базе FastAPI

Теперь, когда мы создали наш запрос GraphQL, давайте инициализируем FastAPI и назначим нашу службу GraphQL маршруту индекса.

Затем давайте запустим следующую команду на нашем терминале, чтобы запустить наше приложение FastAPI:


Давайте вставим следующий запрос на левую панель и выполним вызов нашего API, нажав кнопку запуска:

Мы должны получить такой ответ:


Получение только одного курса

Давайте посмотрим, как сделать запрос, чтобы получить данные только для одного курса. Мы добавим параметр id в наш запрос, чтобы наш сервер GraphQL знал, что нам нужен только курс, который соответствует id . Чтобы это сработало, давайте заменим наш класс Query приведенным ниже кодом:

В строке 3 нашего нового класса запросов мы заключили значение get_course в тип поля, который позволяет нам добавлять наши параметры запроса. Здесь мы добавили идентификатор param типа String . Мы также включили параметр id в метод resolve_get_course() и дали ему значение по умолчанию None , чтобы сделать его необязательным.

В строках 7-9 мы добавили условие, которое возвращает только тот курс, который соответствует идентификатору, если он указан. Нам также нужно будет добавить тип поля к нашему импорту графена, прежде чем мы двинемся дальше:

Теперь мы можем пойти дальше и получить только один курс, который соответствует идентификатору со следующим запросом:

Мы должны получить это в качестве нашего ответа:

Мутации GraphQL

Мы видели, как настроить наш сервер GraphQL с FastAPI и получать данные с него. Теперь давайте посмотрим, как мы можем использовать мутации GraphQL для добавления новых курсов в наше хранилище данных или обновления существующих курсов. Начнем с добавления типа Mutation к нашему импорту graphene :

Теперь мы можем создать класс, названный CreateCourse по типу Mutation :

В нашем классе CreateCourse мы начали с создания переменной для нашего курса, которую мы обернули в класс Field . Это то, что мы вернем пользователю после успешного создания курса.

Затем мы перешли к созданию класса для наших аргументов мутации. Наши аргументы здесь id , title и instructor . Нам нужно будет предоставить эту информацию при внесении нашей мутации CreateCourse .

Далее нам понадобится метод создания курсов mutate . Здесь мы будем использовать аргументы, предоставленные пользователем, для создания нового курса в нашем хранилище данных. В этом случае мы изменим наш файл courses.json . Однако в продакшен приложении вам, вероятно, потребуется база данных, и, как упоминалось ранее, FastAPI поддерживает как реляционные, так и нереляционные базы данных.

Создадим наш метод mutate . Обратите внимание, что он должен быть назван mutate , так как это то, что ожидает наша служба GraphQL:

В операторе return нашего метода mutate мы вызвали класс CreateCourse и в скобках присвоили вновь созданный курс переменной course , которую мы объявили ранее. Это то, что наш GraphQL API вернет пользователю в ответ на запрос на изменение.

Теперь, когда у нас есть наш класс CreateCourse , давайте создадим новый класс из ObjectType с названием Mutation . Здесь мы будем хранить все наши мутации:

Сделав это, мы можем добавить наш класс Mutation в Schema в вызове функции app.add_route() :

Теперь мы можем проверить это, выполнив следующий запрос в нашем клиенте GraphQL:

И мы должны получить такой ответ:

Обработка ошибок запроса

Непосредственно перед добавлением нового курса в наше хранилище данных в функции CreateCourse mutate вставим следующий код:

Выше мы прошлись по нашему хранилищу данных course_list и проверили, есть ли существующий курс с тем же идентификатором, что и у входящего курса. Если у нас есть совпадение, то должно быть сделано исключение.

В зависимости от базы данных и ORM, которые мы выбираем для нашего приложения, процесс проверки наличия ранее существовавшего значения может отличаться. Однако при возникновении исключения GraphQL всегда возвращает ошибку. С новым изменением в нашем коде CreateCourse , вот как должен выглядеть наш класс мутации:

Теперь мы можем проверить это, попытавшись создать новый курс с уже существующим id . Давайте запустим точную мутацию из последнего запроса CreateCourse в нашем клиенте GraphQL:

В качестве ответа мы должны получить следующее:

Вывод

В этой статье мы узнали основы FastAPI и то, как мы можем использовать его для настройки сервера GraphQL. Сочетание этих двух технологий дает действительно захватывающий опыт веб-разработки.

С GraphQL мы можем относительно легко писать сложные запросы, давая веб-клиентам возможность запрашивать именно то, что они хотят. А с FastAPI мы можем создавать надежные, высокопроизводительные серверы GraphQL с очень небольшим количеством шаблонного кода.

Читайте также: