Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

How should I structure dataProvider and resources for nested API structures? #6595

Answered by BatuhanW
ms-bang asked this question in Q&A
Discussion options

Hello, I'm using Refine in my new project. However, I've encountered the following problem.
I understood that we define resources and use them as a basis for data fetching in the dataProvider, but how should we define them for nested API structures? Looking at the getList part, should we use conditional statements to check and make API requests every time a resource is added? This structure doesn't seem like a good approach! If not, I would appreciate it if you could point me to some references!

export const resources = [
 {
 name: 'users',
 list: '/users',
 },
 {
 name: 'company-managements/companies',
 list: '/company-managements/companies',
 },
 {
 name: '/company-managements/companies/:companyId/departments',
 list: '/company-managements/companies/:companyId/departments',
 },
];
import { DataProvider } from '@refinedev/core';
import { createApi } from '@/lib/api/axios';
import { ApiResponse } from '@/types/common/api';
export const dataProvider = (url: string): DataProvider => {
 const api = createApi();
 return {
 getList: async ({ resource, meta }) => {
 if (resource === 'departments') {
 const response = await api.get<ApiResponse<any[]>>(
 `${url}/company-managements/companies/${meta?.companyId}/${resource}`
 );
 const { data } = response.data;
 return {
 data,
 total: data.length,
 };
 }
 const response = await api.get<ApiResponse<any[]>>(`${url}/${resource}`);
 const { data } = response.data;
 return {
 data,
 total: data.length,
 };
 },
 getOne: async ({ resource, id }) => {
 const response = await api.get<ApiResponse<any>>(
 `${url}/${resource}/${id}`
 );
 return {
 data: response.data.data,
 };
 },
 getMany: async ({ resource, ids }) => {
 const response = await api.get<ApiResponse<any[]>>(`${url}/${resource}`, {
 params: { ids },
 });
 return {
 data: response.data.data,
 };
 },
 create: async ({ resource, variables }) => {
 const response = await api.post<ApiResponse<any>>(
 `${url}/${resource}`,
 variables
 );
 return {
 data: response.data.data,
 };
 },
 update: async () => {
 throw new Error('Not implemented');
 },
 deleteOne: async ({ resource, id }) => {
 const response = await api.delete<ApiResponse<any>>(
 `${url}/${resource}/${id}`
 );
 return {
 data: response.data.data,
 };
 },
 getApiUrl: () => url,
 };
};

image

You must be logged in to vote

Hello @ms-bang, resource object also accepts parent field, you can utilize that one.

export const resources = [
 {
 name: 'users',
 list: '/users',
 },
 {
 name: 'company-managements',
 hide: true // probably we don't want to show it in the sidebar.
 },
 {
 name: 'companies',
 list: '/company-managements/companies', // you can still keep this nested, since it's path on the client side.
 meta: {
 parent: 'company-managements',
 }
 },
 {
 name: 'departments',
 list: '/company-managements/companies/:companyId/departments',
 meta: {
 parent: 'companies',
 },
 },
];
// In your data provider
console.log(meta.parent)
console.log(meta.compan...

Replies: 1 comment 2 replies

Comment options

Hello @ms-bang, resource object also accepts parent field, you can utilize that one.

export const resources = [
 {
 name: 'users',
 list: '/users',
 },
 {
 name: 'company-managements',
 hide: true // probably we don't want to show it in the sidebar.
 },
 {
 name: 'companies',
 list: '/company-managements/companies', // you can still keep this nested, since it's path on the client side.
 meta: {
 parent: 'company-managements',
 }
 },
 {
 name: 'departments',
 list: '/company-managements/companies/:companyId/departments',
 meta: {
 parent: 'companies',
 },
 },
];
// In your data provider
console.log(meta.parent)
console.log(meta.companyId)

Then in your data provider, meta.parent will be available for your use-case.

You must be logged in to vote
2 replies
Comment options

Thank you for answering my question! @BatuhanW

I have one more inquiry. Is it appropriate to modify the URL using conditional statements based on the resource within the dataProvider when making requests?

If there is a better approach, I would greatly appreciate your recommendations.

Comment options

Am I possibly misunderstanding how this works?

When I assign the name "companies" to the resource and then use the useList function, does it mean that the resource will use the list method and follow the URL structure /company-managements/companies?

Additionally, when I run console.log(resource), it displays companies.

If possible, I would be very grateful if you could explain how to configure the dataProvider, preferably with code examples.

Answer selected by BatuhanW
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet
2 participants

AltStyle によって変換されたページ (->オリジナル) /