GraphQl结合两个解析器
目前,我有两个解析器,作者和书籍,它们从两个单独的API返回数据。在大多数情况下,我只需要致电一个或另一个,但是,在这种情况下,我需要将书籍附加到作者。 我不清楚我该怎么做。
选项1-易于执行
我称其为作者解析器中的API并在此处组合。这意味着我有可能对API进行不必要的电话。这也意味着,如果本书API更改,我必须对作者和书籍解析器进行更新,而不仅仅是更新书籍解析器。
选项2 -Resolver
是否有办法从作者解析器中调用书籍解析器?
选项3-客户端
是否有办法将作者缝合并从客户端查询中进行预订?
我是GraphQL和Type-graphQL的新手,如果这很明显,则很抱歉。
作者
const author = {
name: 'James',
bookIds: [1, 2]
};
book
const book = {
id: 1,
title: 'Book 1'
};
所需的结果
const author = {
name: 'James',
books: [{
id: 1,
title: 'Book 1'
},
{
id: 2,
title: 'Book 2'
}]
}
解析器
@Service()
@Resolver(() => Author)
export class AuthorResolver {
constructor(private readonly authorService: authorService) { }
@Query(() => Author)
async author(
@Arg('authorId', () => ID, { nullable: false }) authorId: string,
@Ctx() { dataSources }: ResolverContext
): Promise<Author | undefined> {
const { authorService } = dataSources;
const author = await this.author.getAuthor(authorService, authorId);
return {
id: author.id,
name: author.name,
bookIds: author.bookIds
};
}
}
@Service()
@Resolver(() => Book)
export class BookResolver {
constructor(private readonly bookService: bookService) { }
@Query(() => Book)
async book(
@Arg('bookId', () => ID, { nullable: false }) bookId: string,
@Ctx() { dataSources }: ResolverContext
): Promise<Book | undefined> {
const { bookService } = dataSources;
const book = await this.book.getBook(bookService, bookId);
return {
id: book.id,
title: book.title
};
}
}
客户端查询
query BookQuery($bookId: ID!) {
book(bookId: $bookId) {
id
title
}
}
query authorQuery($authorId: ID!) {
book(authorId: $authorId) {
id
name
books
}
}
I currently have two resolvers, Authors and Books, that return data from two separate API's. In most scenarios I only need to call one or the other, however, in this scenario, I need to attach the books to the author.
It's not clear to me how I should do this.
Option 1 - Simple to do
I call the book API in the Author resolver and combine them here. This means I'd potentially make unnecessary calls to the Book API. It also means if the book API changes, I'd have to make updates to both the author and book resolvers instead of just updating the Book resolver.
Option 2 - Resolver
Is there a way to call the Book resolver from within the Author resolver?
Options 3 - Client
Is there a way to stitch the author and book together from within the client query?
I’m new to graphql and type-graphql so apologies if this is obvious.
Author
const author = {
name: 'James',
bookIds: [1, 2]
};
Book
const book = {
id: 1,
title: 'Book 1'
};
Desired outcome
const author = {
name: 'James',
books: [{
id: 1,
title: 'Book 1'
},
{
id: 2,
title: 'Book 2'
}]
}
Resolvers
@Service()
@Resolver(() => Author)
export class AuthorResolver {
constructor(private readonly authorService: authorService) { }
@Query(() => Author)
async author(
@Arg('authorId', () => ID, { nullable: false }) authorId: string,
@Ctx() { dataSources }: ResolverContext
): Promise<Author | undefined> {
const { authorService } = dataSources;
const author = await this.author.getAuthor(authorService, authorId);
return {
id: author.id,
name: author.name,
bookIds: author.bookIds
};
}
}
@Service()
@Resolver(() => Book)
export class BookResolver {
constructor(private readonly bookService: bookService) { }
@Query(() => Book)
async book(
@Arg('bookId', () => ID, { nullable: false }) bookId: string,
@Ctx() { dataSources }: ResolverContext
): Promise<Book | undefined> {
const { bookService } = dataSources;
const book = await this.book.getBook(bookService, bookId);
return {
id: book.id,
title: book.title
};
}
}
Client Side Query
query BookQuery($bookId: ID!) {
book(bookId: $bookId) {
id
title
}
}
query authorQuery($authorId: ID!) {
book(authorId: $authorId) {
id
name
books
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您必须实现 fieldResolver ,称为
books> books
,,在作者
解析器中。如果未来的API发生变化,则不会影响解析器,因为您使用与API交谈并充当中间件层的服务。
该服务必须得到很好的实现(抽象),并且返回的实体必须正确匹配/映射到GraphQl对象类型。 IE无需
返回{id:rutian.id,...}
在解析器内部,因为它是由服务和类映射自动完成的。&nbsp;此外,您可以在解析器内注入服务实例,因此无需使用
@ctx
并获取相同的服务实例:只需使用this。[service_name]。[方法] 。
使您的上下文尽可能简单(例如,通过a jwt )。
最终
作者
解析器更加干净,更便携:如果您想要示例项目,请参见 this 。
You must implement a FieldResolver, called
books
, in theAuthor
resolver.If an API changes in the future, it will not affect the resolver since you use a service that talks to the API and acts as a middleware layer.
The service must be well implemented (abstraction) and the returned entity must be matched/mapped correctly to a GraphQL object type. i.e. there is no need to
return {id: author.id, ...}
inside a resolver since it's done automatically by the service and class mappings.Moreover, you inject a service instance inside the resolver, so there is no need to use
@Ctx
and obtain the same service instance: simply usethis.[SERVICE_NAME].[METHOD]
.Keep you context as simple as possible (e.g. authenticated user id obtained by a JWT).
The final
Author
resolver is much cleaner and more portable:If you want an example project, see this.