【问题标题】:How can I get Absinthe and Dataloader to work together?我怎样才能让苦艾酒和 Dataloader 一起工作?
【发布时间】:2021-02-25 18:23:36
【问题描述】:

我有一个 GraphQL api,它使用传统的解析函数可以正常工作。我的目标是消除 N+1 问题。

为此,我决定使用 Dataloader。我已经完成了这些步骤,应该让应用程序运行:


  1. 我将这两个函数添加到我的上下文模块中:
defmodule Project.People do
  # CRUD...

  def data, do: Dataloader.Ecto.new(Repo, query: &query/2)

  def query(queryable, _params) do
    queryable
  end
end
  1. 我在 Schema 模块中添加了 context/1plugins/0 并更新了查询解析器:
defmodule ProjectWeb.GraphQL.Schema do
  use Absinthe.Schema

  import Absinthe.Resolution.Helpers, only: [dataloader: 1]

  alias ProjectWeb.GraphQL.Schema
  alias Project.People

  import_types(Schema.Types)

  query do
    @desc "Get a list of all people."
    field :people, list_of(:person) do
      resolve(dataloader(People))
    end

    # Other queries...
  end

  def context(context) do
    loader =
      Dataloader.new()
      |> Dataloader.add_source(People, People.data())

    Map.put(context, :loader, loader)
  end

  def plugins, do: [Absinthe.Middleware.Dataloader | Absinthe.Plugin.defaults()]
end

官方教程中没有给出其他步骤。我的:person 对象如下所示:

@desc "An object that defines a person."
  object :person do
    field :id, :id
    field :birth_date, :date
    field :first_name, :string
    field :last_name, :string
    field :pesel, :string
    field :second_name, :string
    field :sex, :string

    # field :addresses, list_of(:address) do
    #   resolve(fn parent, _, _ ->
    #     addresses = Project.Repo.all(Ecto.assoc(parent, :addresses))

    #     {:ok, addresses}
    #   end)
    #   description("List of addresses that are assigned to this person.")
    # end

    # field :contacts, list_of(:contact) do
    #   resolve(fn parent, _, _ ->
    #     contacts = Project.Repo.all(Ecto.assoc(parent, :contacts))

    #     {:ok, contacts}
    #   end)
    #   description("List of contacts that are assigned to this person.")
    # end
  end

注释部分是在没有数据加载器的情况下工作并且不会导致问题的解析器。

当我尝试查询时:

{
  people { 
    id
  }
}

我明白了:

Request: POST /graphiql
** (exit) an exception was raised:
    ** (Dataloader.GetError)   The given atom - :people - is not a module.

  This can happen if you intend to pass an Ecto struct in your call to
  `dataloader/4` but pass something other than a struct.

我没有完全理解错误消息,因为我确实将一个模块传递给了dataloader/1,但我找不到解决方案。可能是什么情况?

【问题讨论】:

    标签: graphql elixir ecto dataloader absinthe


    【解决方案1】:

    我已经设法让它工作了——方法如下:

    数据加载器本身并不知道从数据库中提取什么,它只了解关联。因此dataloader(People) 只能是object 块的一部分,而不是query 块的一部分。

    换句话说:

    defmodule ProjectWeb.GraphQL.Schema do
      use Absinthe.Schema
    
      import Absinthe.Resolution.Helpers, only: [dataloader: 1]
    
      alias ProjectWeb.GraphQL.Schema
      alias Project.People
    
      import_types(Schema.Types)
    
      query do
        @desc "Get a list of all people."
        field :people, list_of(:person) do
          resolve(&StandardPerson.resolver/2)
        end
    
        # Other queries...
      end
    
      def context(context) do
        loader =
          Dataloader.new()
          |> Dataloader.add_source(People, People.data())
    
        Map.put(context, :loader, loader)
      end
    
      def plugins, do: [Absinthe.Middleware.Dataloader | Absinthe.Plugin.defaults()]
    end
    

    @desc "An object that defines a person."
      object :person do
        field :id, :id
        field :birth_date, :date
        field :first_name, :string
        field :last_name, :string
        field :pesel, :string
        field :second_name, :string
        field :sex, :string
    
        field :addresses, list_of(:address) do
          resolve(dataloader(People))
          description("List of addresses that are assigned to this person.")
        end
    
        field :contacts, list_of(:contact) do
          resolve(dataloader(People))
          description("List of contacts that are assigned to this person.")
        end
      end
    

    【讨论】:

      猜你喜欢
      • 2017-12-24
      • 2014-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-03
      • 2012-04-22
      • 2013-03-28
      • 2013-04-26
      相关资源
      最近更新 更多