Я использую Absinthe для создания GraphQL API.Хранилище данных - Dgraph , в котором в качестве языка запросов используется GraphQL +.Он похож на GraphQL, но не идентичен.
Теоретически это поставило бы меня в прекрасную ситуацию.Запрос GraphQL, такой как
query {
user {
id
username
posts {
title
text
comments {
text
}
}
}
}
, может быть также одним запросом в Dgraph.Это выглядело бы почти идентично:
{
users(func: has(type_user))
{
id
username
posts {
title
text
comments {
text
}
}
}
}
Я хотел бы использовать эту мощь графовых баз данных для загрузки сложных отношений за один раз.Проблема в том, что в абсенте схема должна быть составной.В схеме будет один :user
объект, который имеет поле :posts
, которое будет list_of(:post
).И тогда объект :post
.И т. Д.
Чтобы предотвратить N + 1 запросы, вы бы использовали загрузчик данных или пакетную загрузку.
Теперь я могу просто загрузить все за один раз.Я мог бы, например, написать распознаватель, который делает именно это:
defmodule MyApp.Resolvers.User do
alias MyApp.Users
def users(_, _args, _) do
{:ok, Users.all()}
end
end
И пользовательский контекст, который фактически запрашивает db
defmodule MyApp.Users do
alias MyApp.Users.User
def all do
query = """
{
users(func: has(type_user))
{
id
username
posts {
title
text
comments {
text
}
}
}
}
"""
case ExDgraph.query(conn(), query) do
{:ok, msg} ->
%{result: %{users: users}} = msg
Enum.map(users, fn x -> struct(User, x) end)
{:error, _error} ->
[]
end
end
end
Проблема здесь в том, что я перегружаюсь.Я ВСЕГДА запрашиваю все, даже если мне нужен только список пользователей.Это работает, но не очень хорошая производительность.И я теряю возможность компоновки.
Что было бы решением, если бы у меня был доступ к запросу в распознавателе, чтобы понять, какие поля запрашиваются.Затем я мог бы использовать сопоставление с образцом для построения запроса и затем отправить его в Dgraph.Я мог бы даже иметь один центральный преобразователь и много построителей запросов.Но мне нужно подключиться к запросу и разобрать его напрямую.
Возможно ли что-то подобное?Любая идея, где я мог бы найти что-то интересное, чтобы решить эту проблему?Может быть, с промежуточным программным обеспечением абсента?
Спасибо!