С легкостью справляйтесь с операциями CRUD

Подход «Сначала схема» — это не что иное, как определение схемы для нашего сервиса GraphQL, а затем реализация кода путем сопоставления определений в определенной нами схеме.

Для этого мы будем использовать библиотеку Ariadne.

Ariadne — это библиотека Python для реализации серверов GraphQL с использованием подхода сначала схема. — ариадна

Обзор проекта

Мы собираемся создать сервер GraphQL, который обрабатывает CRUD-операцию книги в книжном магазине.

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

Серверные операции

  • Добавить книги
  • Получить книгу по ID
  • Список книг по жанру
  • Список всех книг
  • Обновить книгу
  • Удалить книгу

Создание сервера GraphQL

Установка библиотеки

Мы сильно зависим от библиотеки Ariadne, поэтому мы должны установить ее.

pip install ariadne

Мы должны сделать наш сервер GraphQL HTTP-сервером, который будет получать HTTP-запросы, выполнять запросы GraphQL и возвращать ответы.

Для этого мы можем использовать сервер ASGI (Asynchronous Server Gateway Interface), такой как uvicorn.

pip install uvicorn

Определение нашей схемы

Я предлагаю вам определить схему и реализовать код по-своему и согласно вашим требованиям. Здесь мы увидим мой способ определения схемы.

Я планировал иметь несколько типов объектов GraphQL, которые могут содержать некоторую информацию о Books в нашей книге store.

Здесь у меня есть 2 типа объектов и 1 тип перечисления на данный момент для описания книги.

Booktype имеет следующие поля:

  • title — Строковый тип и необнуляемый
  • book_id — тип идентификатора
  • genre — тип перечисления
  • author — массив из Author типов и необнуляемый

Author тип:

  • name — тип String и не может принимать значения NULL
  • почта — строковый тип

BookGenreтип перечисления:

  • имеет два значения (FICTION, NONFICTION)

Вышеуказанные типы являются основными типами для обработки информации Books.

Теперь мы переходим к определению точки входа для нашего сервиса GraphQL.

Тип запроса

У меня есть указанный выше тип запроса с 3 полями.

  • book — получить информацию о книге, указав book_id в аргументе
  • books — получить список доступных книг
  • getbooks — получить список книг требуемого жанра. Аргумент getgenre является необязательным, по умолчанию он имеет значение FICTION.
type GetBookResult{
    isexists: Boolean!
    book: Book
}

Тип GetBookResult имеет 2 поля:

  • isexists — логический тип, не допускающий значения NULL, указывает, существует ли информация о книге для данного book_id.
  • book — Тип книги

Тип мутации

Тип мутации имеет 3 поля

  • add_book — создать книжный ресурс в нашем магазине книг, предоставив входные данные, а ответ — статус этого запроса.
  • update_book — обновляет информацию о существующей книге, и ответом является статус этого запроса.
  • delete_book — удаляет книгу с заданным id книги и возвращает статус операции.

Вышеуказанные типы используются в поле add_book типа Mutation.

Типы UpdateInput и PutStatus используются в поле update_book типа Mutation.

type DeleteStatus{
    iserror: Boolean!
    description: String
}

Тип DeleteStatus используется в поле delete_book типа Mutation.

Мы подошли к концу нашего определения схемы. Переходим к реализации кода.

Реализация сервера GraphQL

Магазин в памяти

Как я упоминал ранее, я буду использовать хранилище данных в памяти (просто переменную) для хранения информации о книге.

BOOK_STORE = [
    {
        "title": "Book 1", "book_id": 1, "genre": "FICTION",
        "authors": [{"name": "Logesh", "mail": "[email protected]"}]
    },
]

Здесь у меня есть начальные фиктивные данные.

Стандартный код

Мы можем загрузить нашу схему двумя способами:

  • определяя нашу схему в переменной
  • определяя нашу схему в отдельном файле .graphql

Например, в первом случае:

from ariadne import QueryType, gql, make_executable_schema, MutationType
from ariadne.asgi import GraphQL
type_defs = gql("""
        type Query {
            book(book_id : ID!): GetBookResult
            books: [Book]
        }
    """)
query = QueryType()
mutation = MutationType()
schema = make_executable_schema(type_defs, query, mutation)
app = GraphQL(schema, debug=True)

Для второго случая:

from ariadne import QueryType, make_executable_schema, MutationType, load_schema_from_path
from ariadne.asgi import GraphQL
query = QueryType()
mutation = MutationType()
book_type_defs = load_schema_from_path("book_schema.graphql")
schema = make_executable_schema(book_type_defs, query, mutation)
app = GraphQL(schema, debug=True)

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

Вспомогательные функции

Я написал несколько вспомогательных функций, таких как получение информации о книге из BOOK_STORE:

Приведенная выше функция используется для получения книги с заданным идентификатором из переменной BOOK_STORE (наша база данных).

Эта функция используется для проверки существования книги с заданным идентификатором.

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

Чтобы удалить книгу из переменной BOOK_STORE, укажите идентификатор книги.

Эта функция используется для получения списка книг заданного жанра.

Резольверы

Теперь мы готовы реализовать наши преобразователи GraphQL Server.

Для поля book типа запроса у нас есть вышеуказанная функция для разрешения запроса и возврата словаря с ключами (полями), которые мы упомянули в нашем типе ответа этого запроса в схеме.

Приведенные выше функции преобразователя используются для разрешения полей запроса — books и getbooks.

Теперь переходим к типу Mutation.

Вышеупомянутая функция используется для создания новой книги в нашем магазине Book.

resolve_update_bookфункция используется для обновления существующей книги.

Эта функция используется для удаления книги путем предоставления идентификатора книги.

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

Обслуживание клиентов

Используя uvicorn, мы собираемся заставить наш сервер GraphQL работать через HTTP.

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

uvicorn main:app
# uvicorn <filename>:<GraphQL object>

Uvicorn работает на http://127.0.0.1:8000

Книга запросов

Мутация add_book

Книги запросов

Книга обновлений мутаций

Книга запросов

Гетбуки запросов

Мутация delete_book

Книга запросов

Мы также можем использовать Postman в качестве клиента GraphQL.

В этой статье мы увидели, как создать собственный сервер GraphQL на Python (первый подход схемы).

Вы можете найти этот проект на моем Github. Спасибо за прочтение.