私の質問は、複雑なカスタム リゾルバーを構築する方法と、それらが組み込みのリゾルバーとうまく連携しない理由に関するものです。複雑なリゾルバーに関する良い例を見つけることができず、実際のケースはこの例よりもさらに複雑です。
次のスキーマがあります
type Query {
users: [User!]! @field(resolver: "App\\Library\\UserController@fetchAll")
posts: [Post!]! @field(resolver: "App\\Library\\PostController@fetchAll")
post(id: Int! @eq): Post @find
}
type User {
id: ID!
name: String
posts: [Post!]! @field(resolver: "App\\Library\\PostController@fetchAll")
}
type Post {
id: ID!
content: String!
comments: [Comment] @field(resolver: "App\\Library\\CommentController@fetchAll")
}
type Comment {
id: ID!
reply: String!
commentRating: [CommentRating] @field(resolver: “App\\Library\\CommentRatingController@fetchSum")
}
type CommentRating {
id: ID!
rating: String
}
たとえば、このクエリがあります
{
users {
id,
name
posts {
title
comments {
id,
reply
}
}
}
}
ビジネスロジックのためにカスタムリゾルバーが必要ですが、すべてではありません。上記は機能します(すべてのカスタムリゾルバーを意図的に使用しています。少し説明します)が、正しく呼び出される最初のリゾルバーで雄弁なクエリを作成した場合のみです。そのようです
// Function in custom resolver. All other custom resolver which are accessed can just pass the $rootValue on, or operate on it.
public function fetchAll($rootValue, array $args, GraphQLContext $context, ResolveInfo $resolveInfo)
{
// We have some more sophisticated logic to dynamically build the array parameter on the line below, because the query may not always request comments, which means 'posts.comments' wont be needed. As this is the entrypoint, $rootValue is empty
$t = User::with['posts', 'posts.comments', 'posts.comments.ratings'])->get();
// Business logic modules called here
return $t;
}
カスタムリゾルバーから始めたが、クエリ内の何かが組み込みのリゾルバーを使用している場合、たとえば、
type User {
id: ID!
name: String
posts: [Post!]! @field(resolver: "App\\Library\\PostController@fetchAll")
}
に
type User {
id: ID!
name: String
posts: [Post!]! @all
}
その後も正常に動作しますが、N+1 の問題が発生します。そのため、MySQL ログで、複数のクエリが突然実行されていることがわかります。これは、カスタムのみ、または組み込みのリゾルバーのみを使用している場合には発生しません。カスタム リゾルバーに組み込みリゾルバーを呼び出させるのは悪い習慣ですか?
私のすべてのタイプのカスタムリゾルバーに固執するのが最善ですか? そして、カスタムリゾルバーを構築する私のアプローチは正しい方法ですか? (パブリック関数 fetchAll コードニペットを参照)