refine
refine copied to clipboard
[BUG] Hasura Data Provider - Allow remote schemas and possibility to change ID type
Describe the bug
When a remote schema is imported into Hasura, the grouping relationships are called as {table}_aggregated instead of {table}_aggregate. Right now the Hasura dataProvider always expects that the name of the aggregation table is suffixed with aggregated.
We can see this in https://github.com/refinedev/refine/blob/next/packages/hasura/src/dataProvider/index.ts#L215 Aggregate Problem
const hasuraFilters = generateFilters(filters);
const operation = metaData?.operation ?? resource;
const aggregateOperation = `${operation}_aggregate`;
const hasuraSortingType = `[${operation}_order_by!]`;
const hasuraFiltersType = `${operation}_bool_exp`;
The same goes for the Hasura id field, which is forced by the data provider to be a uuid and cannot be of the numeric or string type.
https://github.com/refinedev/refine/blob/next/packages/hasura/src/dataProvider/index.ts#L162
UUID Problem
getOne: async ({ resource, id, metaData }) => {
const operation = `${metaData?.operation ?? resource}_by_pk`;
const { query, variables } = gql.query({
operation,
variables: {
id: { value: id, type: "uuid", required: true },
...metaData?.variables,
},
fields: metaData?.fields,
});
const response = await client.request(query, variables);
return {
data: response[operation],
};
},
Is it possible to parameterize these cases in some way or give a solution to the problem?
Steps To Reproduce
For aggregated problem:
- Go to Hasura and export a remote Schema
- Try to get the list through Hasura Data Provider with useList hook.
- Try to execute the next query generated by the dataProvider:
query: "query ($limit: Int, $offset: Int, $where: users_test_bool_exp) { users_test (limit: $limit, offset: $offset) { id, name, lastname, email, genre, role } users_test_aggregate (where: $where) { aggregate { count } } }" variables: {limit: 20, offset: 0}
For uuid problem:
You could find this problem is your example case of Hasura DataProvider when you try to access to the detail of a post:
-
Install your hasura data provider sample: npm create refine-app@latest -- --example data-provider-hasura
-
access to: http://localhost:3000/posts
-
Access to the detail of a post:
-
See the network error {"errors":[{"extensions":{"code":"validation-failed","path":"$.selectionSet.posts_by_pk.args.id"},"message":"variable 'id' is declared as 'uuid!', but used where 'Int!' is expected"}]}
Expected behavior
Give the possibility of defining these use cases for different data schemas by parameterization.
Screenshot
No response
Desktop
- OS
- Browser: Last Chrome
- Data Provider: @pankod/refine-hasura
Mobile
No response
Additional Context
No response
Hey @diegoarda for the UUID problem, you can solve it temporarily.
import { useResource } from "@pankod/refine-core";
....
const { id } = useResource();
const { queryResult } = useShow<IPost>({
metaData: {
fields: [
"id",
"title",
{
category: ["title"],
},
"content",
],
// override variables
variables: {
id: { value: id, type: "Int", required: true },
},
},
});
However, as a definitive solution, dataProvider
can only be added to client
as well as idType
.
Can you open a pr for solving these problems to support us? 🙏
I don't understand at all your answer. Do you see better that the option is added to Hasura's GraphQLClient
? It's constructor could be new GraphQLClient(url, options, config)
where config could be { idType: 'Int' }
.
About remote schemas problem, could you fix it?
Thanks a lot!
Hey @diegoarda
I think the temporary solution is not for you. Let me explain my solution in more detail.
You can copy the data provider files to your project and make changes as follows. You can solve this quickly.
const dataProvider = (client: GraphQLClient, options?: { idType: string } }): Required<DataProvider> => {
https://github.com/refinedev/refine/blob/next/packages/hasura/src/dataProvider/index.ts#L154
If you want to contribute to the refine for this topic, you can create a PR 🙏
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Hey @diegoarda
I think the temporary solution is not for you. Let me explain my solution in more detail.
You can copy the data provider files to your project and make changes as follows. You can solve this quickly.
const dataProvider = (client: GraphQLClient, options?: { idType: string } }): Required<DataProvider> => {
https://github.com/refinedev/refine/blob/next/packages/hasura/src/dataProvider/index.ts#L154
If you want to contribute to the refine for this topic, you can create a PR 🙏
i will try to create PR for this issue
Hey @zulianrizki, thanks! We are looking forward to it.