graphql - Absinthe 结果具有所有空值
问题描述
我对 Elixir、Phoenix 和 Absinthe 完全陌生……所以放轻松。:)
我正在使用一个名为 Dlex 的库来试验一个名为Dgraph的图形数据库。我编写了一个简单的查询,旨在查找并返回用户列表(目前我只有两个用户):
def list_users() do
query = """
{
users(func: type(User)) {
uid
email
name
}
}
"""
{:ok, %{"users" => result}} = Dlex.query(:dlex, query)
IO.inspect(result)
{:ok, result}
end
的输出IO.inspect(result)
正是我所期望和想要的——我的两个用户的列表:
[
%{"email" => "rob@example.com", "name" => "Rob", "uid" => "0x1"},
%{"email" => "bridget@example.com", "name" => "Bridget", "uid" => "0x2"}
]
但是,当我使用 GraphiQL 运行此查询时,结果中的所有值都null
出于某种原因:
{
"data": {
"users": [
{
"email": null,
"name": null,
"uid": null
},
{
"email": null,
"name": null,
"uid": null
}
]
}
}
知道我做错了什么吗?
解决方案
在我看来,您可能会在用户解析器中返回适当的数据,但有一个例外:当 Absinthe 为每个用户解析字段时,默认解析器仅将字段作为原子键查找。当它在父映射中找不到:uid
, :email
,时,它返回。:name
nil
您可以将结果转换为将原子作为键。如果你想走这条路,一个选择就是映射每个用户并明确复制你想要的。
users = Enum.map(users, &%{uid: &1["uid"], email: &1["email"], name: &1["name"]})
不过,这是您在添加密钥时需要更新的另一个地方。并且许多尝试更动态的解决方案并没有遵循最佳实践(他们打开应用程序以在运行时创建新原子,这是一个坏主意,或者当他们看到无法识别的键时抛出错误)。
我过去使用的一种解决方案是创建自己的默认 MapGet 中间件,用于检查 atom 和 string 键。
defmodule MyAppWeb.GraphQL.Middleware.MapGet do
@moduledoc """
Default resolver that checks for both atom and string keys.
"""
@behaviour Absinthe.Middleware
@impl Absinthe.Middleware
def call(%{source: source} = info, key) do
value =
with :error <- Map.fetch(source, key),
:error <- Map.fetch(source, to_string(key)) do
nil
else
{:ok, value} ->
value
end
%{info | state: :resolved, value: value}
end
end
Absinthe 文档描述了更换默认中间件。在我的应用程序中,它非常简单。
defmodule MyAppWeb.GraphQL.Schema do
use Absinthe.Schema
# ...
def middleware(middleware, field, object) do
map_get = {{MyAppWeb.GraphQL.Middleware.MapGet, :call}, field.identifier}
Absinthe.Schema.replace_default(middleware, map_get, field, object)
end
# ...
end
推荐阅读
- javascript - IndexedDB 对象到 jQuery 自定义触发事件?
- shell - 如何使 xargs 执行的 shell 脚本接受用户输入?
- java - 我可以使用不同的 kafka 代理集来存储 Kafka 流应用程序的状态吗?
- spring-boot - Spring scheduler - 获取下一个事件的时间
- autodesk-forge - Autodesk forge 在 Forge Configurator 发明者中自定义转换对象
- flutter - 如何使用 Navigator 2.0 更新页面内容
- sql-server - 尝试使用 PutDatabaseRecord 从数据库中的.parquet 转储数据时,Nifi 中出现错误
- php - PHP按多个值排序数组:正/负然后是第二个值
- typescript - 如何为整个项目运行 JetBrains WebStorm 重构“更改 ES6 导入”
- assembly - 如何在 Mips 的井字游戏中显示当前的棋盘