Elixir:使用Absinthe查询图表数据库Dgraph。 GraphQL到GraphQL +映射

时间:2018-06-03 23:22:46

标签: elixir graphql dgraph absinthe

我正在使用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
      }
    }
  }
}

图形数据库一次性加载复杂关系的能力是我想要使用的。问题只是:在Absinthe中,模式应该是可组合的。在架构中,将有一个:user对象,其:posts字段为list_of(:post。然后是:post个对象。等等。

为了帮助阻止N + 1查询,您可以使用dataloader或批量加载。

现在我可以一次性加载所有内容。例如,我可以编写一个解析器:

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。我甚至可以有一个中央解析器和许多查询构建器。但我需要挂钩查询并直接解析它。

这样的事情可能吗?知道在哪里可以找到有趣的东西来解决这个问题吗?也许与Absinthe中间件?

谢谢!

1 个答案:

答案 0 :(得分:0)

我想我找到了解决方案。让我们拿一个解决方案来获取用户列表。像这样:

object :user_queries do
  field :users, list_of(:user) do
    resolve fn _parent, _, resolution ->
      IO.inspect(resolution.definition.selections)
      {:ok, Users.all()}
    end
  end
end

如果您使用嵌套查询点击它,请执行以下操作:

{
  users {
    id
    name
    posts {
      id
      title
      text
      comments {
        id
        text
      }
    }
  }
}

您将在终端中看到复杂的嵌套地图。它包含我们需要的所有信息。选择包含字段。每个字段都有一个名称。如果它有一个嵌套对象,它又包含一个列表selections

现在我们只需要沿着兔子洞走下去,为我们的Dgraph查询收集信息并相应地构建它。由于它已经通过了苦艾酒验证等,它看起来是一个不错的选择。

有趣的是,如果这样的方法会导致Absinthe带来的优化问题,比如在已经获取的对象的内存缓存中......