gpt4 book ai didi

graphql - 我怎样才能让苦艾酒和 Dataloader 一起工作?

转载 作者:行者123 更新时间:2023-12-04 01:11:03 27 4
gpt4 key购买 nike

我有一个 GraphQL api,使用传统的解析函数可以很好地工作。我的目标是消除 N+1 问题。
为此,我决定使用 Dataloader。我已经完成了这些步骤,据说可以让应用程序运行:

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

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

    def query(queryable, _params) do
    queryable
    end
    end
  • 我添加了 context/1plugins/0到 Schema 模块并更新了查询的解析器:
  • 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我找不到解决方案。可能是什么情况?

    最佳答案

    我已经设法让它工作了——方法如下:
    数据加载器本身并不知道从数据库中提取什么,它只了解关联。因此dataloader(People)只能是 object 的一部分 block ,而不是 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

    关于graphql - 我怎样才能让苦艾酒和 Dataloader 一起工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64826080/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com