[FEAT] Passing arbitrary graphql variables to hasura dataProvider
tomoemon opened this issue · 7 comments
Is your feature request related to a problem? Please describe.
I am very pleased that gqlQuery allows us to perform arbitrary GraphQL Queries against hasura.
#5489
However, it is not possible to use hasura's powerful filters because only CrudFilter[] can be passed to filters in the useTable. It is also not possible to use variables type information generated by graphql codegen.
In my case.
Given a type with the relation User has many Books, I can write a query in hasura to get a list of Users who have 3 or more Books, which is not possible in the current CrudFilter.
Describe alternatives you've considered
added to the following line in hasura dataProvider.
variables = {
...hasuraPagination,
...(hasuraSorting &&
(namingConvention === "graphql-default"
? {
orderBy: hasuraSorting,
}
: {
order_by: hasuraSorting,
})),
...(hasuraFilters && {
where: hasuraFilters,
}),
...(meta?.gqlVariables && meta?.gqlVariables), // added
};
https://github.com/refinedev/refine/blob/master/packages/hasura/src/dataProvider/index.ts#L181
This allows the addition of any where condition supported by hasura, using type information hints, as follows.
const { tableProps } = useTable<GetFieldsFromList<BlogPostsQuery>>({
syncWithLocation: true,
meta: {
gqlQuery: BlogPostsDocument,
gqlVariables: {
where: {
_and: [
{
title: {
_ilike: "%test%",
},
}
],
},
} as BlogPostsQueryVariables, // generated type from graphql query
},
});
Additional context
No response
Describe the thing to improve
- add
gqlVariables?: any
toGraphQLQueryOptions
- Ideally, I would like to pass the type information generated from the graphql query by type parameter instead of any, but I can't think of a way to achieve that right now.
- use
meta.gqlVariables
ingetList
,getMany
of hasura dataProvider
Hello @tomoemon, thanks for the issue.
It seems like a good idea, but can you give me the GQL Query you want to generate so I can better understand the problem? Maybe we can make CrudFilter[] to support this.
@alicanerdurmaz Thank you for your response!
For example, I want to execute the following query
Trying to get a list of categories that have at least one Posts with the string "test" in the title.
If Posts is related to another type, I may add more nested filters. This is often the case when I want to filter the items to be displayed with complex business logic.
query Categories {
categories(
where: {
posts_aggregate: {
count: {
predicate: { _gte: 1 },
filter: {
content: { _ilike: "%test%" }
}
}
}
}
) {
id
title
}
}
schema
type Posts {
id: ID!
title: String!
content: String!
categories: Categories!
}
type Categories {
id: ID!
title: String!
posts: [Posts!]!
posts_aggregate: posts_aggregate!
}
In my opinion, such a condition would be too complex to add to the CrudFilter. Writing complex filter conditions without type completion may also cause bugs.
@tomoemon Thanks for the detailed explanation, we'll see what we can do.
Hey @tomoemon I think you should use meta.gqlQuery
and meta.gqlMutation
fields. There you can pass your GraphQL queries created with graphql-tag
.
https://refine.dev/docs/data/packages/hasura/#usage-with-graphql-tag
@BatuhanW
I don't understand why it was closed.
Do you mean that I should put a specific filter condition directly on the where argument in the gql tagged query?
If so, I can use any filter in hasura, but then how do I give it a dynamic value?
Hey @tomoemon, you are right. I think we can accept extra meta.gqlVariables
field in the hooks and pass it to the query variables inside data provider.
We are open to contributions for this. This feature can be applied to following packages:
@refinedev/hasura
@refinedev/graphql
@refinedev/nestjs-query