首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >apollo-server -有条件地从选择集中排除字段

apollo-server -有条件地从选择集中排除字段
EN

Stack Overflow用户
提问于 2019-08-29 12:38:37
回答 1查看 99关注 0票数 1

我遇到这样一种情况:在查询的解析器之前,我想有条件地从查询选择中排除一个字段。

用例是,我的底层API仅根据用户的区域设置公开特定的“字段”,如果请求的字段没有包含在该区域设置中,则对此API的调用将抛出错误。

我尝试了一种使用指令的方法,

代码语言:javascript
复制
type Person {
    id: Int!
    name: String!
    medicare: String @locale(locales: ["AU"])
}

type query {
    person(id: Int!): Person
}

使用SchemaDirectiveVisitor.visitFieldDefinition,当用户区域设置与指令中定义的任何区域设置都不匹配时,我覆盖medicare字段的field.resolve以返回null。

但是,当使用非"AU"语言环境的客户端执行以下操作时

代码语言:javascript
复制
query {
  person(id: 111) {
      name
      medicareNumber
    }
  }
}

永远不会调用medicare的字段解析器,查询解析器向底层medicareNumber发出请求,将选择集中的字段(包括无效的API )作为查询参数追加。此时,API调用返回一个错误对象。

我相信这是有意义的,因为指令解析器似乎在FieldDefinition上,并且只有在person解析器返回有效结果时才会被调用。

有没有一种方法可以实现这种功能,不管有没有指令?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-29 19:26:32

一般来说,我会告诫不要进行这种模式设计。作为客户机,如果我在选择集中包含一个字段,我希望在响应中看到该字段--从服务器端的选择集中删除该字段是违反规范的,并且可能导致不必要的混乱(特别是在较大的团队或使用公共API时)。

如果您正在检查请求的字段以确定要传递给API调用的参数,那么强制某个字段解析为null不会有任何作用--该字段仍将包含在选择集中。事实上,实际上没有办法创建一个会影响请求选择集的模式指令。

这里最好的方法是: 1)确保模式中任何可能为空的字段都可以为空;2)无论选择集到参数逻辑在哪里,都显式地过滤选择集。

编辑:

模式指令不会作为info中返回的模式对象的一部分出现,因此它们不能用作标志。我的建议是维护一个单独的内存映射。例如:

代码语言:javascript
复制
const fieldsByLocale = {
  US: {
    Person: ['name', 'medicareNumber'],  
  },
  AU: {
    Person: ['name'],
  },
}

然后,您只需访问适当的列表即可使用fieldsByLocale[context.locale][info.returnType]进行过滤。此过滤逻辑特定于您的数据源(在本例中为外部API),因此这比用属于存储层的信息“污染”模式要干净一些。如果API发生变化,或者您完全切换到此信息的不同来源(如数据库),则可以在不接触类型定义的情况下更新解析器。实际上,通过这种方式,过滤逻辑可以很容易地存在于域/服务层中,而不是您的解析器中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57703062

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档