Nested Resources
The API that I am integrating with has a lot of nested resources. As an example (i.e not actual api url):
GET/POST/PATCH/DELETE https://api.com/v1/resourceA
GET/POST/PATCH/DELETE https://api.com/v1/resourceA/resourceAName/resourceB
GET/POST/PATCH/DELETE https://api.com/v1/resourceA/resourceAName/resourceB/resourceBName/resourceC
What is the best practice way of setting up the data provider for such an API? Should I create a custom data provider for https://api.com/v1, pass in resourceAName as an id, and resourceBName/resourceCName/etc. as metadata? Or should I create separate custom data providers for each resource? Both of these seem a bit convoluted for a use case that seems like it would be common place, so I assume there must be a better way to do this.
Thank you!
24 Replies
Hey @misstsuliu 👋,
You can use "resource" property of data/form/table hooks 🚀
https://refine.dev/docs/faq/#how-can-i-request-an-api-with-nested-route
FAQ | refine
How can I change the form data before submitting it to the API?
notable-jade•2y ago
Hi guys, I'm trying to do a nested resource as explained above, but the call to the endpoint doesn't contain the nested resource.
On my App resources props I pass the name
merchants
but in my pages, I provide the resource subpath/merchants
to useTable
and useForm
, but it continues to use the one specified as name merchants
without the subpath
It seems to work with useTable
if I prefix the resource with a slash like /subpath/merchants
but then I need to strip that slash in the construction of the url in the dataProvider.
Anyway, this trick doesn't seem to work with useForm
I'm a bit confused on the correct way to get nested resource working.
Anyone can help me with this ?Hey @moinax ,
Welcome, we are glad to see you 💯 Nested resource definitions are only used for routing, but you can use the
resource
property of the data/form/table hooks
Example:
foreign-sapphire•2y ago
@moinax which package do you import
useForm
and useTable
from ?
There should not be any issue with the override when you pass resource
prop but let me check 🤔notable-jade•2y ago
Mmm, it's coming from the @pankod/refine-antd
Thanks. Yep that's how I did it actually, but something goes wrong
foreign-sapphire•2y ago
checking now, i'll get back to you asap
Hey @moinax, sorry for the late response 🙏 I just checked with
@pankod/refine-antd@3.70.0
and @pankod/refine-core@3.88.0
. Could not reproduce the useTable
issue,
Once, i thought i did but turns out it was because the network tab in the developer tools only shows the last segment at the name column in network tab 😅 but it was actually sending requests to abc/def
(even though it was showing def
only)
For the useForm
, also could not reproduce but I want to mention a case that might help you with this issue or in the future 😅
There was a case about using multiple useForm
hooks in a single route let's say you're in posts/edit/15
and you also want to be able to edit the categories inside a modal or some section or anything. You add another useForm
with a resource:"categories"
, but now if we make a request with just knowing the resource
in the second useForm
, we will be sending a request for categories/15
which is not the intended behavior.
So if you pass a resource
property to the useForm
you also need to pass id
as well to avoid unwanted API calls.
To get the id
, you can use useParams
hook from your router provider or you can access the useParams
from useRouterContext
hook in @pankod/refine-core
Can you update your dependencies if they are old and can you check the request details to make sure its sending a request to the wrong endpoint? If so, can you please try to provide a minimal repro, because I could not reproduce the issues we're mentioning 😅 🙏notable-jade•2y ago
Thanks a lot, I'll have a look at this right now. For the request in the network tab, I knew it already and that was not the issue ( because my backend was answering a 404 error) 😉
I'll see if my dependencies are up-to-date, but I started a week ago or so, so it should not be that far away.
If it doesn't work I'll try to share you a minimal repo
notable-jade•2y ago
Hello again, I tried with the latest packages, but didn't change a thing.
I created a gist with the files I think we need to check https://gist.github.com/Moinax/347ca2cdb775f47d4fb96541fc28da5d
Let me know if it's enough for you or if you need something more.
The only thing that I didn't mention earlier is the fact that I put the
merchants
resource into a parent to get a submenu, maybe that's the issue.Gist
Refine ant-design nested resources
Refine ant-design nested resources. GitHub Gist: instantly share code, notes, and snippets.
foreign-sapphire•2y ago
Thats the issue probably, we match the resource by the route or mock one with the provided resource and since you have a a subpath defined in the resources prop; its going to match with the merchants resource 🧐 I will going to check this one to fix the confusion but while this is going to fixed, I think you can try defining the resource name as "subpath/merchants" with options.label as "merchants" and options.route as "merchants" 🤔
notable-jade•2y ago
That's actually what I did initially and work pretty well (except the toaster displaying an encoded version of
subpath/merchants
in the message).
But I was trying this because we have a few nested resources like subpath/merchants/{id}/something/{id}
and I wanted to check if it was even possible without doing it full custom
BTW, I tried without the parent route, but I still have issues. The list is working as expected, but:
1. When I create a merchants
it calls the right endpoint /subpath/merchants
but then it redirects to the wrong refine page subpath/merchants
instead of merchants
2. When I try to edit a merchants
it calls the wrong endpoint /merchants
instead of mbrella_pay/merchants
foreign-sapphire•2y ago
Looks like the first one is also related to the previous issue we’ve talked about. When you do provide a custom resource you also need to set
redirect
to false
🤔 but this needs to change i think, i dont think this is ever an intended outcome in any case.
For the second, that should not happen when you provide a custom resource. I will try to have a look today to have an answer for it 😅notable-jade•2y ago
Thanks a lot
again, I can't find any documentation on how to build a multi level menu/resource structure like below:
Is it possible without to much pain ?
It seems really easy to build a flat structure, but I can't find anything about nested resources filtering.
The idea is to be able to filter all sub-resources on the selected organisation.
Thanks in advance for your help
![moinaxLove](https://cdn.discordapp.com/emojis/738942086203572314.png)
foreign-sapphire•2y ago
Hey @moinax let me get back on my keyboard in couple mins and i will try to give an answer to that 😅
conscious-sapphire•2y ago
Hi!
I have a similar issue!
foreign-sapphire•2y ago
Hey again,
First of all this topic and couple similar ones inspired us to change the way we handle routing to let users to be free when they're designing their apps. Hopefully, there will be great changes on this field with our next major release and we're planning do this in near future. Thanks to everyone involved! 🙏 👏
Unfortunately, our
<Sider />
component, by default does not support this also, it's same for our routers too. But we offer custom routes that can be defined easily so you can create your routes in any shape you want. (Here's a good starting point if you don't know how https://refine.dev/docs/advanced-tutorials/custom-pages/#public-custom-pages)
When you finally define your routes as you like, you can run swizzle
command to export & customize the Layout components (It may export multiple components and you can remove them if you want, for now all you need is the <Sider/> component) (To learn more about swizzle
, here's the docs: https://refine.dev/docs/packages/documentation/cli/#swizzle)
After that, I think the renderTreeView
function may become handy while implementing this kind of multi-level menu, it may need some modification but it can give you a hint on how 😅
While you're developing a custom <Sider />
you'll be able to use the refine data hooks just like the other components/pages so it won't be hard to fetch and transform them to create a menu 😅
Let me know if you have any issues while customizing the sider or creating the custom routes, I'll try to answer them as soon as possible 🚀
@los._.ko hope the above message is helpful to you too 😅
When you define a custom route, refine hooks will not be able to get the resource and id parameters from the route and you'll probably need to pass them manually 🤔
But with the next major, we'll definitely have more flexible and simpler API for that 🤣