React-admin's Resource
component maps name
prop value to an endpoint.
E.g. to access data from . http://example.com/abc
, your Resource
component looks like this:
<Resource name='abc'/>
What i want to access resource at http://example.com/abc/def
?
This <Resource name='abc/def'/>
doesn't even call the dataProvider
function.
I wouldn't want to end up with ugly solution like:
// App.js
<Resource name='def'/>
// dataProvider.js
if (resource==='def') {
url = 'abc/def'
}
Do resources names always have to be without /
? Any hacks?
I'm working on a project where we ended up writing our own dataProvider since our api is not strictly restful.
It's a bit of a pita to wrap your head around but once you figure out the workflow it's not too bad.
Basically there are three things that happen when dataProvider is called
Here's a link to the relevant part of the react-admin documentation https://marmelab.com/react-admin/DataProviders.html#writing-your-own-data-provider
Our solution uses switch statements whose cases are types and then each case has logic to handle different resources.
I'm not sure if this is the intended implementation but we ended up with something like this:
// import all the things
// set your api path prefix
const convertDataProviderRequestToHTTP = (type, resource, params) => {
//switch statement with one case for each action type
// and some logic where necessary for different resources ie.
switch(type){
case "GET_ONE":{
// if statements to handle resources with goofy endpoints
if(resource === 'abc/def'){
const url = `${API_PREFIX}/abc/def`;
const options = {
// set the specific options that you need for a
// each particular resource
}
}
// handles resources with normal restful endpoints
const url = `${API_PREFIX}/${RESOURCE}`;
const options = {
// this part depends on how you're doing your fetching
// might need to include the particular rest verb
// and any other settings
}
}
}
return {
url,
options
}
}
const convertHTTPResponseToDataProvider = (response, type, resource, params){
// another switch statement that converts the response that you get
// from your api to something that's useful to your Resource
switch(type){
case 'GET_ONE':{
if(resource === 'abc/def'){
// convert response into something useful and return it
return{
data: convertedResponse
}
}
}
}
}
export default (type, resource, params) => {
// this comes from react-admin, you could use plain old fetch or
// your favorite fetch library like axios instead
const { fetchJson } = fetchUtils;
// part 1, using the stuff that was sent in the dataProvider
// call to generate what you need to sending your fetch
const { url, options } = convertDataProviderRequestToHTTP(
type,
resource,
params
);
// add logic for grabbing your tokens and adding headers to options here
options.headers.set('headerkey', 'headervalue');
// part 2 sending the fetch request
return fetchJson(url, options).then(response =>
// part 3, converting the response and returning it
convertHTTPResponseToDataProvider(response, type, resource, params)
);
};
As the app has grown we ended up breaking it up into separate files so it's easier to read but it seems to be working out ok for us so far.
I had to install the redux browser tool and insert lots of logging statements to sort of step through it and get a better idea of what happens and when it happens. After getting the first action type/resource combo working it sort of clicked and adding to it since then has been pretty easy to figure out.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With