react-admin中可以有多个dataProvider吗?

Cur*_*urt 7 reactjs react-admin

如果我有多个不同的REST API后端(分别做不同事情的应用程序),并且我想要一个能够对由这些后端管理的实体进行CRUD的UI(基于反应管理)的应用程序,我很好奇是否可以连接react-admin来做到这一点。

我想象的不是这个(单个/全局dataProvider):

const App = () => (
    <Admin dataProvider={simpleRestProvider('http://path.to.foo.api')}>
        <Resource name="foos" list={FooList} />
    </Admin>
);
Run Code Online (Sandbox Code Playgroud)

我们可以做这样的事情(特定于资源的dataProviders):

    const App = () => (
        <Admin >
            <Resource name="foos" list={FooList} 
               dataProvider={simpleRestProvider('http://path.to.foo.api')} />
            <Resource name="bars" list={BarList} 
               dataProvider={simpleRestProvider('http://path.to.bar.api')} />
        </Admin>
    );
Run Code Online (Sandbox Code Playgroud)

无论如何,如果您对如何在react-admin中对多个后端进行REST提出了建议,我将非常感激。

Hải*_*Bùi 9

解决方案 2021,React admin版本 3.12.x 以上

我从@Gildas Garcia 的回答中得到了这个想法。非常感谢@Gildas Garcia。但是你的代码只能在 React admin 版本 2 上工作,在版本 3 及更高版本中,我需要一些定制才能使其工作。这是我的解决方案

// ... others import
import {
  fetchUtils,
  GET_LIST,
  GET_ONE,
  CREATE,
  UPDATE,
  UPDATE_MANY,
  DELETE,
  GET_MANY,
  GET_MANY_REFERENCE,
} from 'react-admin';

const dataProviders = [ 
  {
    dataProvider: simpleRestProvider('http://localhost:3000'),
    resources: ['users'],
  },
  {
    dataProvider: simpleRestProvider('http://localhost:3002'),
    resources: ['roles'],
  },
  {
    dataProvider: customJSONDataProvider('http://localhost:3003'),
    resources: ['permissions'],
  },
];

export default (type, resource, params) => {
  const dataProviderMapping = dataProviders.find((dp) =>
    dp.resources.includes(resource));

  const mappingType = {
    [GET_LIST]: 'getList',
    [GET_ONE]: 'getOne',
    [GET_MANY]: 'getMany',
    [GET_MANY_REFERENCE]: 'getManyReference',
    [CREATE]: 'create',
    [UPDATE]: 'update',
    [UPDATE_MANY]: 'updateMany',
    [DELETE]: 'delete',
  };

  return dataProviderMapping.dataProvider[mappingType[type]](resource, params);
};
Run Code Online (Sandbox Code Playgroud)


Gil*_*cia 8

不,但是您可以拥有一个超级dataProvivder,它将根据资源选择合适的一个。就像是:

const dataProviders = [
    { dataProvider: simpleRestProvider('http://path.to.foo.api'), resources: ['foos'] },
    { dataProvider: simpleRestProvider('http://path.to.bar.api'), resources: ['bars'] },
];

export default (type, resource, params) => {
    const dataProviderMapping = dataProviders.find(dp => dp.resources.includes(resource));

    return dataProviderMapping.dataProvider(type, resource, params);
}
Run Code Online (Sandbox Code Playgroud)


tac*_*one 5

React Admin 3 采用了新的 dataProviders 接口,所有答案似乎仅适用于 React Admin 2。

以下是我为在 React Admin 3 上运行所做的工作:

class CompositeDataProvider {
  constructor(dataProviders) {
    this.dataProviders = dataProviders;
  }

  _delegate(name, resource, params) {
    const { dataProvider } = this.dataProviders.find((dp) =>
      dp.resources.includes(resource)
    );

    return dataProvider[name](resource, params);
  }

  getList(resource, params) {
    return this._delegate("getList", resource, params);
  }
  getOne(resource, params) {
    return this._delegate("getOne", resource, params);
  }
  getMany(resource, params) {
    return this._delegate("getMany", resource, params);
  }
  getManyReference(resource, params) {
    return this._delegate("getManyReference", resource, params);
  }
  create(resource, params) {
    return this._delegate("create", resource, params);
  }
  update(resource, params) {
    return this._delegate("update", resource, params);
  }
  updateMany(resource, params) {
    return this._delegate("updateMany", resource, params);
  }
  delete(resource, params) {
    return this._delegate("delete", resource, params);
  }
  deleteMany(resource, params) {
    return this._delegate("deleteMany", resource, params);
  }
}

export default CompositeDataProvider;

Run Code Online (Sandbox Code Playgroud)

然后你可以这样使用它:

const dataProvider = new compositeDataProvider([
  {
    dataProvider: jsonServerProvider("https://jsonplaceholder.typicode.com"),
    resources: ["posts", "users"],
  },
  {
    dataProvider: simpleRestProvider("http://path.to.bar.api"),
    resources: ["bars"],
  },
]);
Run Code Online (Sandbox Code Playgroud)

它仍然是准系统,但它给了你一个可以改进的想法。