JavaRush /Курсы /Модуль 3: Django /Введение в сложные запросы в GraphQL

Введение в сложные запросы в GraphQL

Модуль 3: Django
25 уровень , 0 лекция
Открыта

GraphQL славится своей гибкостью, так как позволяет запрашивать ровно те данные, которые нужны, и ровно в том формате, в каком они нужны. Именно поэтому в реальных приложениях мы часто сталкиваемся с необходимостью обработать сложные запросы. Так что, если раньше мы строили простые "вопросики" к API вроде "Дай мне список всех пользователей", то теперь переходим к созданию сложных "допросов" вида: "Дай мне список всех пользователей с их заказами, но только за последний месяц, а ещё добавь комментарии к заказам".

Зачем нужны сложные запросы?

Представьте, что у вас есть приложение для интернет-магазина, и вы хотите получить данные об определённом пользователе с его заказами, включая список товаров в каждом заказе. В REST API вам пришлось бы сделать несколько запросов, чтобы собрать всю информацию. GraphQL позволяет сделать это за один запрос! Это упрощает жизнь клиенту (меньше запросов) и делает API более удобным для использования.

Пример запроса:

query {
  user(id: 1) {
    name
    email
    orders {
      id
      total
      items {
        product {
          name
          price
        }
        quantity
      }
    }
  }
}

Этот запрос позволяет вложенно получить данные о пользователе, его заказах и товарах в каждом заказе. Красота, правда?

Основные концепции сложных запросов

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

  1. Соединение данных из нескольких моделей

GraphQL легко позволяет извлекать данные из связанных моделей. Например, вы можете получить данные из таблицы пользователей, а затем сразу связать её с таблицей заказов, используя связь ForeignKey в Django. Всё это делается через GraphQL-схему, без необходимости писать дополнительный SQL или изобретать велосипед.

  1. Обработка больших объемов данных

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

Пример неэффективного запроса:

query {
  users {
    id
    name
    orders {
      id
      items {
        id
      }
    }
  }
}

Если у вас 1000 пользователей с тысячами заказов, сервер «захлебнется» от такого запроса. Мы научимся, как этого избежать.

Типы сложных запросов

  1. Запросы с вложениями (Nested Queries)

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

Пример:

query {
  article(id: 1) {
    title
    content
    author {
      name
      email
    }
    comments {
      text
      user {
        name
      }
    }
  }
}

Этот запрос извлекает данные не только о статье, но и о её авторе, а также о каждом комментарии и комментаторе.

  1. Запросы с фильтрами

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

Пример:

query {
  orders(filter: { date_gte: "2023-01-01", date_lte: "2023-01-07" }) {
    id
    total
    user {
      name
    }
  }
}

Мы передали в запрос аргумент filter, чтобы ограничить выборку.

Примеры сложных запросов

Пример 1: пользователи с их ролями и правами доступа

Допустим, у нас есть модели User, Role и Permission. Один пользователь может иметь несколько ролей, а роль может включать несколько прав.

GraphQL запрос:

query {
  users {
    id
    name
    roles {
      name
      permissions {
        name
      }
    }
  }
}

Django модель:

class Permission(models.Model):
    name = models.CharField(max_length=100)

class Role(models.Model):
    name = models.CharField(max_length=100)
    permissions = models.ManyToManyField(Permission)

class User(models.Model):
    name = models.CharField(max_length=100)
    roles = models.ManyToManyField(Role)

Результат:

{
  "data": {
    "users": [
      {
        "id": 1,
        "name": "Alice",
        "roles": [
          {
            "name": "Admin",
            "permissions": [
              { "name": "Can View" },
              { "name": "Can Edit" }
            ]
          }
        ]
      }
    ]
  }
}

Пример 2: заказы пользователя с товарами

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

GraphQL запрос:

query {
  user(id: 1) {
    name
    orders {
      id
      date
      items {
        product {
          name
          price
        }
        quantity
      }
    }
  }
}

Django модель:

class Product(models.Model):
    name = models.CharField(max_length=200)
    price = models.DecimalField(max_digits=10, decimal_places=2)

class OrderItem(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    quantity = models.IntegerField()

class Order(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    items = models.ManyToManyField(OrderItem)
    date = models.DateTimeField(auto_now_add=True)

Рекомендации по работе со сложными запросами

  1. Контролируйте вложенность. Не позволяйте клиентам делать запросы с бесконечной вложенностью. Это можно ограничить через настройки GraphQL движка (например, max_depth).

  2. Используйте DataLoader для оптимизации. Это поможет бороться с проблемой N+1 запросов, о которой мы поговорим в следующих лекциях.

  3. Добавляйте фильтры. Ограничьте количество возвращаемых данных, чтобы сервер не обрабатывал миллионы записей.

  4. Используйте директивы. GraphQL позволяет использовать директивы для управления включением или исключением данных.

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

1
Задача
Модуль 3: Django, 25 уровень, 0 лекция
Недоступна
Создание базового сложного запроса
Создание базового сложного запроса
1
Задача
Модуль 3: Django, 25 уровень, 0 лекция
Недоступна
Запрос информации о книге и авторе
Запрос информации о книге и авторе
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ