指定要使用的解析器 |解析器顺序
Posted
技术标签:
【中文标题】指定要使用的解析器 |解析器顺序【英文标题】:Specify resolver to use | Resolver order 【发布时间】:2020-01-14 01:59:08 【问题描述】:我正在使用 Apollo 构建一个 GraphQL 服务器。 我遇到了由我的解析器优先级引起的性能问题。
我有一个在父类型上解析的子类型。 Apollo Server 决定使用子类型解析器而不是父类型上更快的解析器。
查询
query getAdGroup($id:ID!)
AdGroup(id:$id)
id
name
Keywords
id
bid
term
设置
AdGroupType(父)
type AdGroup
id
name
keywords(filter: Filter): [Keyword]
关键字类型(子)
type Keyword
id
term
bid
AdGroupResolver.js
// this gets executed
const getKeywords = (handler, adGroupId, filter) => handler.knex.raw(`
select
id,
term,
bid
from keyword
where adGroupId = $adGroupId
`);
export default
Query:
AdGroup: (parent, id: adGroupId , handler ) => getAdGroup(handler, id),
,
AdGroup:
Keywords: ( id: adGroupId , filter , handler ) => getKeywords( handler, adGroupId, filter),
;
KeywordResolver.js
// this gets executed as well
const getKeywordTerm = (handler, keywordId) => handler.knex.raw(`
select
term
from keyword
where keywordId = $keywordId
`);
// this gets executed as well
const getKeywordBid = (handler, keywordId) => handler.knex.raw(`
select
bid
from keyword
where keywordId = $keywordId
`);
export default
Query:
Keyword: (parent, id: keywordId , handler ) => getKeyword(handler, keywordId),
,
Keyword:
term: ( id: keywordId , _, handler ) => getKeywordTerm(handler, keywordId),
bid: ( id: keywordId , _, handler ) => getKeywordBid(handler, keywordId),
;
在一个广告组上请求 1000 多个关键字的响应时间非常长。
但如果我删除关键字解析器上的术语和出价函数,性能会好得多,因为使用了广告组解析器中关键字函数的值。
如何设计我的架构或配置 Apollo 以保持这种灵活性,同时在我要求 AdGroups 关键字时不必单独解析每个关键字?
【问题讨论】:
【参考方案1】:在 GraphQL 中,每个 字段都被解析,并且父字段总是在子字段之前解析(因为父值被传递给子字段的解析器)。如果您不提供解析器,GraphQL 会使用默认解析器函数来尝试在父值上查找匹配的属性(有关更详细的说明,请参阅this answer)。如果您提供解析器,它将始终在每次响应中出现该字段时运行(对于列表,对于列表中的每个项目)。
如果有时父字段已经提供了您要解析的值,而其他时候没有,您可以简单地向您的解析器添加一个条件:
export default
Keyword:
term: ( id: keywordId, term , _, handler ) => term || getKeywordTerm(handler, keywordId),
bid: ( id: keywordId, bid , _, handler ) => bid || getKeywordBid(handler, keywordId),
;
【讨论】:
以上是关于指定要使用的解析器 |解析器顺序的主要内容,如果未能解决你的问题,请参考以下文章