NestJS | GraphQL - 如何解析多个数据集中的嵌套对象列表

Lof*_*tee 2 graphql nestjs

我正在使用 GraphQL 设置一个 NestJS 服务,作为 UI 和多个其他服务之间的中间人。对于此示例,我需要显示来自单个出版商的书籍及其相关信息的列表。

UI 将使用发布者的 ID 访问 Nest 服务。然后我需要调用服务并获取图书 ID 列表。当我有了 ID 列表时,我需要访问两个单独的服务,每个服务都返回每个图书 ID 的对象列表。然后,我需要从两个数据集中构建书籍对象列表。

书籍模型的一个例子是:

export class BookModel {

  @Field(type => BookInformationModel)
  bookInfo: BookInformationModel;

  @Field(type => BookSalesModel)
  bookSales: BookSalesModel;

}
Run Code Online (Sandbox Code Playgroud)

流程的一个示例是:

  1. UI 使用发布者 ID“pub1”访问 Nest 服务
  2. Nest 服务转到出版商服务,该服务返回链接到出版商的图书列表['book1', 'book2']
  3. 然后,Nest 服务会调用返回的 book-info-service[{id: 'book1' title: ...}, {id: 'book2' title: ...}]
  4. 然后,Nest 服务会访问返回的图书销售服务[{price: 123 currency: ...}, {price: 456 currency: ...}]
  5. 将两个数据集映射到 BookModel 列表
[{
  bookInfo: {id: 'book1' title: ...}
  bookSales: {price: 123 currency: ...}
}, {
  bookInfo: {id: 'book2' title: ...}
  bookSales: {price: 456 currency: ...}
}]
Run Code Online (Sandbox Code Playgroud)

这是解析器的简化版本,我遇到了问题:

@Query(returns => [BookModel])
async getBooksByPublisherId(
  @Args('id', { type: () => String }) id: string
) {
  this.publisherService.getBookIds(id)
    .then(response => {
      return response.data;
    })
}

@ResolveField('bookInfo', returns => BookInformationModel)
async getBookInfo() {
  return this.bookInfoService.getBookInfo(bookIds)
}

@ResolveField('bookSales', returns => BookSalesModel)
async getBookSalesInfo() {
  return this.bookSalesService.getSalesInfo(bookIds)
}
Run Code Online (Sandbox Code Playgroud)

我有两个问题:

  1. 如何与字段解析器共享图书 ID 列表?
  2. 我不确定如何编写 的字段解析器bookInfobookSales因为服务返回对象列表。

Lof*_*tee 5

弄清楚了。我需要在 BookModel 上有 bookId。这样,字段解析器就可以通过@Parent.

export class BookModel {

  @Field()
  bookId: string;

  @Field(type => BookInformationModel)
  bookInfo: BookInformationModel;

}
Run Code Online (Sandbox Code Playgroud)
@Query(returns => [BookModel])
async getBooksByPublisherId(
  @Args('id', { type: () => String }) id: string
) {
  this.publisherService.getBookIds(id)
    .then(response => {
      return response.data.map(bookID => ({ bookId }));
    })
}

@ResolveField('bookInfo', returns => BookInformationModel)
async getBookInfo(
  @Parent() bookModel: BookModel
) {
  return this.bookInfoService.getBookInfo(bookModel.bookId)
}
Run Code Online (Sandbox Code Playgroud)