指定要使用的解析器 |解析器顺序

Specify resolver to use | Resolver order

我正在使用 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 关键字时不必要地单独解析每个关键字?

在 GraphQL 中,每个 字段都会被解析,父字段总是在子字段之前被解析(因为父值被传递给子字段的解析器)。如果您不提供解析器,GraphQL 将使用默认解析器函数尝试在父值上找到匹配的 属性(请参阅 以获得更详细的解释)。如果您提供解析器,它会 always 运行 每次该字段出现在响应中(对于列表,对于列表中的每个项目)。

如果有时父字段已经提供了您要解析的值,而有时却没有,您可以简单地向解析器添加一个条件:

export default {
  Keyword: {
    term: ({ id: keywordId, term }, _, { handler }) => term || getKeywordTerm(handler, keywordId),
    bid: ({ id: keywordId, bid }, _, { handler }) => bid || getKeywordBid(handler, keywordId),
  }
};