问题
If I have multiple distinct REST API back-ends (separate apps doing separate things), and I want a single UI (react-admin-based) app that is capable of doing CRUD to entities managed by these various back-ends, I'm curious if it's possible to wire up react-admin to do that.
I'm imagining that instead of this (single/global dataProvider):
const App = () => (
<Admin dataProvider={simpleRestProvider('http://path.to.foo.api')}>
<Resource name="foos" list={FooList} />
</Admin>
);
we could do something like this (resource-specific 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>
);
At any rate, if you have advice on how I can do REST to multiple back-ends in react-admin, I'd appreciate it very much.
回答1:
No, but you can have a super dataProvivder which would select the appropriate one depending on the resource. Something like:
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);
}
回答2:
you can make custom of resource choose to which api you will use. one admin only have one dataProvider.
<Admin
dataProvider={superDataProvider}
/>
but you can do like this:
import superDataProvider from './dataProviderFactory';
following is my code you can reference
import dataProviderRuby from './dataProvider'; //handle ruby dataProvider
import dataProviderJava from './dataProviderForJava';// handle java dataProvider
import { rubyClient, javaClient } from './apolloClient';//custom two diff client one will fetch ruby service ,other will java
const IsOmsResource = resource => {
const omsReource = [
'markets',
'regions',
'countries',
'states',
'items',
'salesOrganizations',
];
return omsReource.some(ele => ele === resource);
}; //those resource will fetch data from java service others will go to ruby
const rubyDataProvider = async (type, resource, params) => {
const provider = await dataProviderRuby({
client: rubyClient,
});
return provider(type, resource, params);
};
const javaDataProvider = async (type, resource, params) => {
const provider = await dataProviderJava({
client: javaClient,
});
return provider(type, resource, params);
};
const superDataProvider = (type, resource, params) => {
if (IsOmsResource(resource)) {
console.log('当前Java', resource);
return javaDataProvider(type, resource, params);
}
console.log('当前ruby', resource);
return rubyDataProvider(type, resource, params);
};
export default superDataProvider;
following is the './apolloClient'
import ApolloClient from 'apollo-client';
import { createHttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { setContext } from 'apollo-link-context';
const httpLinkRuby = createHttpLink({
uri: '/graphql',
});
const httpLinkJava = createHttpLink({
uri: '/oms-graphql',
});
const authLink = setContext((_, { headers }) => {
const token = localStorage.getItem('token');
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : '',
},
};
});
export const rubyClient = new ApolloClient({
link: httpLinkRuby,
cache: new InMemoryCache(),
});
export const javaClient = new ApolloClient({
link: authLink.concat(httpLinkJava),
cache: new InMemoryCache(),
});
来源:https://stackoverflow.com/questions/50724915/is-it-possible-to-have-multiple-dataproviders-in-react-admin