Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT] Passing arbitrary graphql variables to hasura dataProvider #5864

Open
tomoemon opened this issue Apr 18, 2024 · 7 comments
Open

[FEAT] Passing arbitrary graphql variables to hasura dataProvider #5864

tomoemon opened this issue Apr 18, 2024 · 7 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@tomoemon
Copy link

tomoemon commented Apr 18, 2024

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 to GraphQLQueryOptions
    • 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 in getList, getMany of hasura dataProvider
@tomoemon tomoemon added the enhancement New feature or request label Apr 18, 2024
@alicanerdurmaz
Copy link
Member

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.

@tomoemon
Copy link
Author

tomoemon commented Apr 20, 2024

@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.

@alicanerdurmaz
Copy link
Member

@tomoemon Thanks for the detailed explanation, we'll see what we can do.

@BatuhanW
Copy link
Member

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 BatuhanW closed this as not planned Won't fix, can't repro, duplicate, stale Apr 22, 2024
@tomoemon
Copy link
Author

@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?

image

@BatuhanW
Copy link
Member

BatuhanW commented May 2, 2024

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.

@BatuhanW BatuhanW reopened this May 2, 2024
@BatuhanW BatuhanW added the good first issue Good for newcomers label May 2, 2024
@BatuhanW
Copy link
Member

BatuhanW commented May 7, 2024

We are open to contributions for this. This feature can be applied to following packages:

  • @refinedev/hasura
  • @refinedev/graphql
  • @refinedev/nestjs-query

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

3 participants