Введение

Всем привет! Это обсуждение основано на выступлении Ричарда на Strapi Conf о демистификации заполняемой фильтрации Strapi. Полное видео вы можете найти здесь

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

Почему эта дискуссия необходима?

За прошедшие годы Strapi значительно изменился, и наиболее заметные изменения коснулись того, как мы взаимодействуем с нашим контентом. Потребление контента является важной частью процесса взаимодействия с данными. Цель этого поста – помочь вам освоиться с инструментами, необходимыми для эффективного взаимодействия с вашими данными.

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

Начало работы с выборкой населения и полей

Давайте углубимся в концепции популяции и отбора полей.

Как вы можете видеть выше, вы можете войти, только если ваше имя есть в списке. Страпи действует таким же образом с выборкой населения и полей.

По умолчанию Strapi не заполняет и не выбирает ваши отношения автоматически — вы должны делать это вручную.

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

Например, если у вас есть пользователь с статьями (связью), вы не сможете заполнить это отношение, пока не включите разрешение найти. от типа коллекции, как показано ниже.

Итак, вот некоторые вещи, которые следует учитывать при работе с заполнением и фильтрацией в Strapi.

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

Изучение населения и выбора полей на примерах

Давайте рассмотрим несколько примеров. Я создал среду repl, которая использует библиотеку qs для генерации синтаксических строк LHS Bracket, которые мы можем использовать для проверки наших запросов в браузере или с помощью Insomnia.

Вы можете найти repl здесь с простым примером.

Но для простоты я буду использовать инструмент Strapi Query Builder, который вы можете найти здесь.

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

Давайте посмотрим на некоторые примеры отбора населения и полей.

Заполните все с помощью подстановочного оператора

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

Вы можете запустить этот запрос GET в Insomnia, но для краткости мы просто рассмотрим его в браузере.

Вы можете скачать это расширение Chrome, чтобы сделать ваш JSON читабельным.

Обозначение LHS: https://young-spirit-57ca23986d.strapiapp.com/api/articles

Нажмите, чтобы увидеть ответ

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

Если вы хотите вернуть как можно больше информации, используйте подстановочный знак *.

{
  populate: "*",
}

Обозначение LHS: https://young-spirit-57ca23986d.strapiapp.com/api/articles?populate=*

Нажмите, чтобы увидеть ответ

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

При использовании подстановочного оператора * вы будете заполнять отношения, динамические зоны и компоненты только на глубину, равную единице.

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

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

Заполнение конкретных отношений

Чтобы заполнить определенные отношения, мы должны указать, какие поля мы хотим заполнить в Strapi. Давайте посмотрим на следующий пример.

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

Давайте добавим этот запрос на заполнение. Мы можем использовать эту нотацию заполнения массива, чтобы указать, какие поля мы хотим заполнить. Ниже будут получены те же данные, что и при использовании подстановочного знака и заполнении на один уровень для всех указанных элементов.

{
  populate: [
    "cover",
    "category",
    "blocks",
    "authorsBio",
    "seo"
  ],
}

или используя обозначение объекта

{
  populate: {
    cover: {
      populate: true,
    },
    category: {
      populate: true,
    },
    blocks: {
      populate: true,
    },
    authorsBio: {
      populate: true
    },
    seo: {
      populate: true
    }
  },
}

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

Обозначение LHS: https://young-spirit-57ca23986d.strapiapp.com/api/articles?populate[0]=cover&populate[1]=category&populate[2]=blocks&populate[3]=authorsBio&populate[4]=seo

Нажмите, чтобы увидеть ответ

Прежде чем рассмотреть, как мы можем заполнять вложенные отношения, давайте посмотрим, как мы можем заполнить конкретные поля.

Заполнение вложенных отношений

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

Мы рассмотрим, как заполнить дополнительные отношения в нашем отношении authorsBio и компоненте seo.

{
  populate: [
    "cover",
    "category",
    "blocks",
    "authorsBio.avatar",
    "authorsBio.articles",
    "seo.shareImage"
  ],
}

или используя обозначение объекта

{
  populate: {
    cover: {
      populate: true,
    },
    category: {
      populate: true,
    },
    blocks: {
      populate: true,
    },
    authorsBio: {
      populate: ["avatar", "articles"]
    },
    seo: {
      populate: ["shareImage"]
    }
  },
}

Обозначение LHS: https://young-spirit-57ca23986d.strapiapp.com/api/articles?populate[0]=cover&populate[1]=category&populate[2]=blocks&populate[3]=authorsBio.avatar&populate[4]=authorsBio.articles&populate[5]=seo.shareImage

Нажмите, чтобы увидеть ответ

В ответе ниже мы видим заполненные вложенные отношения.

Теперь давайте посмотрим, как выглядит ответ avatar в authorsBio.

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

Заполнение и выбор поля

Теперь мы увидим, как можно указать Strapi возвращать только определенные поля. Мы также увидим, где может быть полезна нотация объекта, поскольку нотация массива не позволяет вам этого сделать.

Пример обозначения массива:

{
  populate: [
    "cover",
    "category",
    "blocks",
    "authorsBio.avatar",
    "authorsBio.articles",
    "seo.shareImage"
  ],
}

Пример обозначения объекта:

{
  populate: {
    cover: {
      populate: true,
    },
    category: {
      populate: true,
    },
    blocks: {
      populate: true,
    },
    authorsBio: {
      populate: ["avatar", "articles"]
    },
    seo: {
      populate: ["shareImage"]
    }
  },
}

Let’s refactor our object notation example to see how to populate only specific fields. We will focus on the authorsBio avatar field.

This is what our original response looked like.

Let’s now only return the name, alternativeText, caption, and url.

To accomplish this, let’s make the following changes to our query.

{
  populate: {
    cover: {
      populate: true,
    },
    category: {
      populate: true,
    },
    blocks: {
      populate: true,
    },
    authorsBio: {
      populate: {
        avatar: {
          fields: [
            "name",
            "alternativeText",
            "caption",
            "url"
          ]
        },
        articles: {
          populate: true,
  }
      }
    },
    seo: {
      populate: ["shareImage"]
    }
  },
}

Обозначение LHS: https://young-spirit-57ca23986d.strapiapp.com/api/articles?populate[cover][populate]=true&populate[category][populate]=true&populate[blocks][populate]=true&populate[authorsBio][populate][avatar][fields][0]=name&populate[authorsBio][populate][avatar][fields][1]=alternativeText&populate[authorsBio][populate][avatar][fields][2]=caption&populate[authorsBio][populate][avatar][fields][3]=url&populate[authorsBio][populate][articles][populate]=true&populate[seo][populate][0]=shareImage

Нажмите, чтобы увидеть ответ

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

В следующем разделе мы рассмотрим сложные заполнения и выбор **полей.

Сложная совокупность и выбор полей

В этом примере вместо получения наших статей мы попытаемся заполнить нашу домашнюю страницу. Сначала мы найдем нашу страницу по слизню. Мы заполним нашу динамическую зону и будем искать только данные для нашего компонента группа отзывов.

Мы построим этот запрос поэтапно.

Для начала давайте найдём нашу страницу по слагу. Мы будем использовать фильтры для фильтрации, где слаг равен home. Более подробно фильтры мы рассмотрим в следующем разделе.

{
  filters: {
    slug: "home";
  }
}

Обозначение LHS: https://young-spirit-57ca23986d.strapiapp.com/api/pages?filters[slug]=home

Нажмите, чтобы увидеть ответ

Получаем следующий ответ.

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

{
  filters: {
    slug: "home"
  },
  populate: {
    contentSections: {
      populate: true,
    }
  }
}

Обозначение LHS: https://young-spirit-57ca23986d.strapiapp.com/api/pages?filters[slug]=home&populate[contentSections][populate]=true

Нажмите, чтобы увидеть ответ

В приведенном выше ответе показаны все элементы contentSections, заполненные до первой глубины.

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

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

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

Давайте сделаем запрос для заполнения следующей динамической зоны.

Мы сосредоточимся на возврате только компонента testimonials-group из нашей динамической зоны с полем title и вложенного компонента testimonials с полем . поля text и authorName.

Давайте внесем следующие изменения.

{
  filters: {
    slug: "home"
  },
  populate: {
    contentSections: {
      on: {
      "sections.testimonials-group": {
        fields: ["title"],
        populate: {
        testimonials: {
          fields: ["text", "authorName"]
        }
        }
      }
      }
    }
  }
}

Обозначение LHS: https://young-spirit-57ca23986d.strapiapp.com/api/pages?filters[slug]=home&populate[contentSections][on][sections.testimonials-group][fields][0]=title&populate[contentSections][on][sections.testimonials-group][populate][testimonials][fiedls][0]=text&populate[contentSections][on][sections.testimonials-group][populate][testimonials][fiedls][1]=authorName

Нажмите, чтобы увидеть ответ

Как видно из ответа, мы возвращаем только компонент testimonials-group из динамической зоны с выбранными полями и вложенный компонент testimonials с указанными полями.

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

Фильтрация данных

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

Вот несколько примеров фильтрации:

Пример фильтрации верхнего уровня

Мы уже видели этот пример, когда фильтровали наши страницы по слагам.

{
  filters: {
    slug: "home";
  }
}

Обозначение LHS: https://young-spirit-57ca23986d.strapiapp.com/api/pages?filters[slug]=home

Нажмите, чтобы увидеть ответ

По умолчанию в приведенной выше записи используется оператор $eq; мы также можем написать это следующим образом.

{
  filters: {
    slug: {
      '$eq': "home"
    }
  }
}

Обозначение LHS: https://young-spirit-57ca23986d.strapiapp.com/api/pages?filters[slug][$eq]=home

Нажмите, чтобы увидеть ответ

Вот несколько примеров распространенных операторов.

| Оператор | Описание | | — — — — — — — | — — — — — — — — — — — — — — — — — — — — | | $eq | Равный | | $ne | Не равно | | $lt | Менее | | $gt | Больше, чем | | $in | Входит в массив | | $notIn | Не включен в массив | | $contains | Содержит | | $notContains | Не содержит | | $null | Имеет значение null | | $notNull | Не является нулевым | | $or | Объединяет фильтры в выражении «или» | | $and | Объединяет фильтры в выражении «и» | | $not | Объединяет фильтры в выражении «не» |

Полный список вы можете увидеть здесь

Давайте найдем страницу, в поле shortName которого установлено значение null.

Мы можем запустить следующий запрос.

{
  filters: {
    shortName: {
      "$null": true
    }
  }
}

Обозначение LHS: https://young-spirit-57ca23986d.strapiapp.com/api/pages?filters[shortName][$null]=true

Нажмите, чтобы увидеть ответ

Фильтрация по примеру отношения

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

{
  populate: {
   authorsBio: {
     fields: ["id", "name", "email"]
   }
  },
  filters: {
    authorsBio: {
      name: {
      "$eq": "Megan"
      },
    }
  }
}

Обозначение LHS: https://young-spirit-57ca23986d.strapiapp.com/api/articles?populate[authorsBio][fields][0]=id&populate[authorsBio][fields][1]=name&populate[authorsBio][fields][2]=email&filters[authorsBio][name][$eq]=Megan

Нажмите, чтобы увидеть ответ

В ответе ниже мы можем увидеть все статьи, написанные Меган.

Комплексная фильтрация

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

В следующем запросе мы хотели бы вернуть только статьи Меган и категорию с именем Strapi, используя наш оператор $and. Обратите внимание, как он принимает массив в качестве аргумента.

{
  fields: ["title"],
  populate: {
   authorsBio: {
     fields: ["name"]
   },
   category: {
     fields: ["name"]
   },
  },
  filters: {
    $and:
      [ { authorsBio: {  name: { "$eq": "Megan" } } }, { category: { name: { "$eq": "strapi" } } }],
    }
}

Обозначение LHS: https://young-spirit-57ca23986d.strapiapp.com/api/articles?fields[0]=title&populate[authorsBio][fields][0]=name&populate[category][fields][0]=name&filters[$and][0][authorsBio][name][$eq]=Megan&filters[$and][1][category][name][$eq]=strapi

Нажмите, чтобы увидеть ответ

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

{
  "data": [
    {
      "id": 1,
      "attributes": {
        "title": "The Benefits of a Headless CMS Like Strapi",
        "authorsBio": {
          "data": { "id": 2, "attributes": { "name": "Megan" } }
        },
        "category": { "data": { "id": 1, "attributes": { "name": "strapi" } } }
      }
    },
    {
      "id": 2,
      "attributes": {
        "title": "Unleashing the Power of Customization with Strapi CMS",
        "authorsBio": {
          "data": { "id": 2, "attributes": { "name": "Megan" } }
        },
        "category": { "data": { "id": 1, "attributes": { "name": "strapi" } } }
      }
    }
  ],
  "meta": {
    "pagination": { "page": 1, "pageSize": 25, "pageCount": 1, "total": 2 }
  }
}

Заключение

В заключение, сегодня мы разоблачили заполнение и фильтрацию в Strapi.

Мы настоятельно рекомендуем, чтобы вы сами писали логику заполнения и фильтрации в своем приложении, а не полагались на внешние плагины, такие как Populate Deep.

Да, это простое решение, но за него приходится платить производительностью, поскольку оно заполняет все данные до указанной глубины.

Судя по тому, что мы рассмотрели выше, заполнение и фильтрация Strapi дают вам детальный контроль над тем, какие данные вы хотите вернуть из своего API.

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

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

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

Как всегда, спасибо, что заглянули, и не забудьте присоединиться к сообществу Strapi на Discord, чтобы обсудить и узнать больше.

Мы работаем ежедневно с понедельника по пятницу с 12:30 по центральному стандартному времени до 13:30 по центральному стандартному времени.

Спасибо за прочтение!