У меня есть запрос
{
"query": "query($withComments: Boolean!) {feed(id: 2) {name comments @include(if: $withComments) {title text}}}",
"vars": {"withComments": true}
}
На основе переменной withComments я могу получить ленту с комментариями или без них. Оно работает. Но похоже, что Сангрия должна получить ленту с комментариями в любом случае (в чем проблема производительности для меня), даже если они мне не нужны и передал withComments со значением false:
val QueryType = ObjectType(
"Query",
fields[GraphQLContext, Unit](
Field("feed", OptionType(FeedType),
arguments = Argument("id", IntType) :: Nil,
resolve = c => c.ctx.feedRepository.get(c.arg[Int]("id")))))
Как правильно включать / исключать списки наследования (например, отношения) в объекте и не выбирать все данные из репозитория, если я не использую @include, сделать репозиторий осведомленным об этом?
Если решение состоит в том, чтобы сделать два запроса feed и feedWithComments, я не вижу никакой гибкости с @include.





Поскольку ваш объект доступа к данным (репозиторий) и схема GraphQL отделены друг от друга, вам необходимо явно распространять информацию о включении / исключении определенных полей.
Есть несколько способов подойти к этому, но я думаю, что самый простой - использовать прогнозы. В вашем случае это может выглядеть так:
val IdArg = Argument("id", IntType)
val QueryType = ObjectType(
"Query",
fields[GraphQLContext, Unit](
Field("feed", OptionType(FeedType),
arguments = IdArg :: Nil,
resolve = Projector(1, (c, projection) ⇒
if (projection.exists(_.name == "comments"))
c.ctx.feedRepository.getWithComments(c arg IdArg)
else
c.ctx.feedRepository.getWithoutComments(c arg IdArg)))))
С Projector я прошу библиотеку предоставить мне 1-уровневую проекцию вложенных полей (только имена полей). Затем на основе этой информации я могу получать данные разными способами (с комментариями или без).
спасибо, это работает, и это именно то, что я хочу, и то, что они рекомендуют делать в документации (только жаль, что без примера). @include сбил меня с ног