Reputation: 111
How to implement a GET_MANY
data provider function in react-admin's ra-data-graphql
package if the GraphQL API only supports the equivalent GET_ONE
?
I understand how it can be done with REST by waiting on resolving all promises of the API call, but here the return from buildQuery
is supposed to be an object with a key for the GraphQL query, and a key for a function parsing the response.
So how can this support multiple GraphQL queries, one for each ID we want to fetch, before we return the result from the data provider for GET_MANY
?
Upvotes: 1
Views: 1536
Reputation: 111
@kurtko sorry for late reply. Just checking this now. Found a workaround that does not require changes to GQL schema (since that is an external API I cannot change).
You need to make changes to ra-data-graphql
. Basically you need to allow for multiple GQL queries and then await until all promises resolve and return a combined result. By using either query
or queries
you can instruct ra-data-graphql to either run a single or multiple GQL queries. I modified index.js as follows:
// GRAPHQL QUERY
if (operation === 'query') {
if (!query.queries) {
// single GraphQL query
const apolloQuery = {
...query,
fetchPolicy: 'network-only',
...getOptions(otherOptions.query, aorFetchType, resource),
};
return client
.query(apolloQuery)
.then((response) => parseResponse(response))
.catch((error) => Promise.reject(error.message));
} else {
// multiple GraphQL queries
const prs = query.variables.map((variables) => {
const { queries, ...rest } = query;
const apolloQuery = {
...rest,
query: queries,
variables,
fetchPolicy: 'network-only',
...getOptions(otherOptions.query, aorFetchType, resource),
};
return client.query(apolloQuery);
});
return Promise.all(prs)
.then((responses) => parseResponse(responses))
.catch((error) => Promise.reject(error.message));
}
}
Upvotes: 1
Reputation: 2126
I had the same problem and solved with schema like this: (look {ids: [ID]}
in UserFilter
it's the important thing)
type Query {
Post(id: ID!): Post
allPosts(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: PostFilter): [Post]
_allPostsMeta(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: PostFilter): ListMetadata
User(id: ID!): User
allUsers(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: UserFilter): [User]
_allUsersMeta(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: UserFilter): ListMetadata
}
type User {
id: ID!
name: String!
views: Int!
}
type Post {
id: ID!
title: String!
views: Int!
body: String
user_id: ID!
User: User
}
input PostFilter {
q: String
id: ID
title: String
views: Int
views_lt: Int
views_lte: Int
views_gt: Int
views_gte: Int
user_id: ID
}
input UserFilter {
q: String
ids: [ID]
title: String
views: Int
views_lt: Int
views_lte: Int
views_gt: Int
views_gte: Int
user_id: ID
}
type ListMetadata {
count: Int!
}
Upvotes: 0