conf-talks

Почему в graphql есть проблема с N+1?

Всем привет! Кто нибудь знает почему в graphql есть изначально эта проблема с n+1 запросов. И одно из решение этой проблемы было реализовано в рамках не самой технологии, а отдельной библиотекой, что скорей всего говорит о том, что для них это не проблема?

Хорошо поставленный вопрос и содержит уже сам в себе ответ.

В реализации самой спецификации GraphQL нет проблемы N+1. Графкуэль берет и выполняет запрос который прислал клиент. Проблема N+1 возникает непосредственно в вашем коде резолверов. В коде который вы написали сами. Если чутка “умнее” написать свой код, например с помощью DataLoader’а, то проблема решается.

Описание проблемы N+1: эта проблема возникает, когда вы запрашиваете Список элементов и к каждому элементу этого списка запрашиваете связные ресурсы. В графкуэль-запросе попросили 100 статей, и к каждой статье запросили данные автора.

Чтобы выполнить такой запрос клиента, необходимо (вариант ИЗИ):

Как такая проблема решается с DataLoader’ом (вариант НОРМ)

Как решается проблема по другому без DataLoader (вариант ХАРД)

——

Как же мы незаметно попадаем на проблему N+1?

На шаге 4 вы ничего страшного не сделали, просто запросили список статей. Корень проблемы в шаге 3 - когда вы его реализовывали, вы даже и не думали что создавая такую простую связь по id через findById, она может быть использована как то “неоптимально”. А именно – будет запрошена кучу раз в одном запросе от клиента.

Итог прост: если вы “связываете” между собой два типа (Post и Author), то старайтесь сделать резолвер подготовленным к множественному вызову в рамках одного запроса. например как написано здесь: https://github.com/nodkz/conf-talks/tree/master/articles/graphql/dataloader

——

Ах, да. Проблема N+1 также существует и с REST API, просто она менее очевидна, но смысл тот же. В тупую дернули список статей, а потом дергаем описание авторов по одному (нагрузка на бэк такая же как и с GraphQL). Как решаете эту проблему с REST API: