新手求助:Apollo GraphQL与react-admin的_allPostsMeta Resolver实现
_allPostsMeta Resolver for react-admin with Apollo & Join Monster Hey there! I totally get how confusing this can be when you're new to Apollo GraphQL Schema and react-admin—let's work through this step by step to get your _allPostsMeta query working correctly.
First, let's make sure we're on the same page about what react-admin expects from _allPostsMeta: this query is used to fetch the total number of posts (especially critical for pagination), so your schema needs a dedicated type for this metadata, plus the query definition.
Step 1: Define the Required Schema Types
First, add a ListMetadata type to your schema, and update your Query type to include _allPostsMeta:
type ListMetadata { total: Int! // This is the total matching post count react-admin relies on } type Query { allPosts(filter: PostFilterInput, sort: PostSortInput): [Post!]! _allPostsMeta(filter: PostFilterInput): ListMetadata! }
This tells GraphQL that _allPostsMeta will return an object with a required integer total value.
Step 2: Build the _allPostsMeta Resolver with Join Monster
You mentioned using Join Monster for resolver configuration—great news, we can reuse its query-building logic to ensure our count matches the filtered results from allPosts.
Important note: Avoid resolver chaining (calling allPosts and taking the array length)! That's inefficient (it pulls all matching posts just to count them) and will give wrong numbers if allPosts uses pagination. Instead, we'll directly query the database for the count.
Here's how to write the resolver:
const resolvers = { Query: { // Your existing allPosts resolver with Join Monster allPosts: joinMonster((resolve, parent, args, context, info) => { return resolve( info, context, sql`SELECT * FROM posts ${joinMonster.where(args.filter)} ${joinMonster.orderBy(args.sort)}` ); }), // The _allPostsMeta resolver we need _allPostsMeta: async (parent, args, context, info) => { // Use Join Monster's query builder to handle filters consistently with allPosts const queryBuilder = joinMonster.getQueryBuilder(info, context, { dialect: 'postgres', // Replace with your database dialect (e.g., 'mysql') }); // Build a SQL query to count matching posts, applying the same filters as allPosts const countQuery = queryBuilder .table('posts') .where(args.filter) // Reuse filters to get accurate, consistent counts .count('* as total') .toQuery(); // Execute the count query using your database connection const result = await context.db.query(countQuery); // Format the result for react-admin return { total: parseInt(result.rows[0].total, 10) }; }, }, };
Key Tips to Avoid Headaches
- Consistent Filtering: By using Join Monster's
where(args.filter), we ensure the count matches exactly whatallPostswould return (even when filters are applied). No more mismatched totals! - Performance: Directly querying for the count is way faster than fetching all posts, especially as your dataset grows.
- Database Context: Make sure
context.dbis your active database connection (e.g., a PostgreSQL client frompgor MySQL client frommysql2) that can execute raw SQL queries.
Test the Resolver
You can verify this works directly in your GraphQL Playground with a query like:
query { _allPostsMeta(filter: { published: true }) { total } }
This should return the total number of published posts, which react-admin will use to handle pagination and display the correct page count.
内容的提问来源于stack exchange,提问作者Greg Belyea

