like-gold
like-gold15mo ago

Resources with the same name on different APIs

Hello Refine community and maintainers! Thanks again for this awesome product, that really helps me to develop stuff faster than ever. I have a very specific question regarding resources. We have two different data-providers (APIs) which both define an Endpoint called "Country". Now both APIs also have a resource called "Town" which has a "country_id" inside (foreign key relation). Is this something, that's possible at all with refine? So far I have created a parent and dataProviderName attribute inside of the meta fields of the resource, but the default APIs (api1) Country is what is being referenced, when I am inside the Country for API (api2). This kind of makes sense as both of them are named Country. The documentation says A resource represents an entity in an endpoint in the API but I don't see how I could narrow down this specific resource more. Help is highly appreciated ✌️
18 Replies
kapa.ai
kapa.ai15mo ago
Hi @bastianwegge. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: Sorry @bastianwegge, I am experiencing especially high traffic right now, please try again. :technologist:
like-gold
like-gold15mo ago
@Omer sorry for tagging here, maybe something you can give me a quick response to? I'd be fine with "Sorry that's not supported" in any case 😅
Omer
Omer15mo ago
hmm I think someone can be help you from @core team
equal-aqua
equal-aqua15mo ago
like-gold
like-gold15mo ago
Thanks for your response Ömer and @alicanerdurmaz ! I was aware of the usage of the hooks refine provides. My case is pretty simple, I have an overlapping resource name, which looks like it's something that cannot be handled by refine. My first resource uses the default data-provider api1, my second resource uses api2. As soon as I go to api2/country refine thinks that it has to retrieve api1/country Yes I can adjust the data-provider inside of the useTable / useMany hooks, but still the "create" button will point to api1/country/create.
Omer
Omer15mo ago
Could you create a CodeSandbox so that we can reproduce this issue? 😅 I think it can save time. You can create a fork from this example, https://refine.dev/docs/examples/data-provider/multiple/
like-gold
like-gold15mo ago
Yes ofc 👍
Omer
Omer15mo ago
thank you for your understanding 🚀
wise-white
wise-white15mo ago
I think what you can do is to use identifier property in your resource definitions and in hooks such as useTable, useOne etc. or components like <List> pass the identifier instead of the name. The resource inference from the router should also work though, like if you define the identifiers like:
resources={[
{ name: "country", identifier: "countryFirst", list: "/country-first", meta: { ... } },
{ name: "country", identifier: "countrySecond", list: "country-second", meta: { ... } },
]}
resources={[
{ name: "country", identifier: "countryFirst", list: "/country-first", meta: { ... } },
{ name: "country", identifier: "countrySecond", list: "country-second", meta: { ... } },
]}
But the buggy thing is, the inference of the resource from the route should be working even without the identifier value 🤔 I'll check this
like-gold
like-gold15mo ago
So the identifier is something that can "further" identify resources? codesandbox is running very slowly and I currently cannot install packages, I will try the identifier in my project and come back to this with a reproduced example. So first thing I notice is that as soon as I use the identifier, I have to declare the dataProviderName inside of useTable (for example). @aliemirs can you give me a hint on where useTable (or useOne) accepts the identifier field? But yes identifier definitely helps to get back to expected behavior! Thanks a lot so far. I'm gonna prepare an example a bit later.
wise-white
wise-white15mo ago
You can pass it with the resource property
like-gold
like-gold15mo ago
Okay so in the end I have to re-define my dataProviderName in every component that depends on that specific data-provider. Unfortunately the identifier flag didn't bring much different. I'll prepare an example now so maybe I'm missing something obvious you might see right away. Okay so here is V1 which is just me asking "shouldn't the inferencer respect the settings from the resources?" -> https://github.com/bastianwegge/refine-resource-duplicate-names Here is version 2, where the inferencer is respecting the dataProviderName. I guess that the inferencer is just looking for the resource here, which would make sense. So I guess all good and expected so far? -> https://github.com/bastianwegge/refine-resource-duplicate-names/tree/2-inferencer-respecting-dataProviderName Here is Version 3, where both resources have a concrete implementation. This time I have to define the dataProviderName in both useTable and useMany, otherwise they (or one of them) will take the default provider. In my opinion this is not what I would expect, as I have the route and the provider inside of my resource definition. Again just me asking "is this intended?". In the end I don't care if I have to duplicate the dataProviderName in every component in the end. https://github.com/bastianwegge/refine-resource-duplicate-names/tree/3-multi-resource-concrete-components Here is Version 4 (last one), where I added the identifier attribute to the resource and to the useTable inside of both the default as well as the typicode post. For the default it works, for the second one it only works if you add the dataProviderName back to the list of values passed into useTable. Again just me asking: What's the purpose of the identifier if not to spare this passed in dataProviderName? Because other than that, I don't see it having any useful effect. https://github.com/bastianwegge/refine-resource-duplicate-names/tree/4-identifier-as-resource
wise-white
wise-white15mo ago
Hey @bastianwegge, actually the identifier is meant to do what you exactly expected 😅 Might be a regression on our side, checking your repro soon. Sorry for the issue
like-gold
like-gold15mo ago
All good, I'm here to help, so maybe it might be the "feature" we want to use. I have also updated this example with another bug I encounter, where the create Button in my List leads to default/posts whereas it should lead to typicode/posts. I guess that's something I have to change inside the layouts? So I found out that this page inside the refine docs (https://refine.dev/docs/api-reference/antd/components/buttons/create-button/) seems to be out-of-date. Antd Table does not have a headerButtons prop. I have created a GitHub Issue for this: https://github.com/refinedev/refine/issues/4432
equal-aqua
equal-aqua15mo ago
thanks for the issue, we will fix 🚀 btw, it should be on list: https://refine.dev/docs/api-reference/antd/components/basic-views/list/#headerbuttons
List | refine
`` provides us a layout to display the page. It does not contain any logic but adds extra functionalities like a create button or giving the page titles.
like-gold
like-gold15mo ago
Thanks for the example @alicanerdurmaz ! The createButtonProps={{ resource: 'my-identifier' }} on the List component did the job for me.
wise-white
wise-white15mo ago
Hey @bastianwegge, sorry for the late response. I checked out your repro, thanks for taking your time to create this 🙏 Identified the issue, in the useTable or any other extension hook of the data hooks of the @refinedev/core, the resource property is not properly passed to the data hooks, resulting with the unwanted behavior in resources with identifiers. While investigating the issue, I also found another minor issue about the data hooks. Initially the primitive data hooks (the ones in the @refinedev/core) were meant to be work without the details of the resource (including the identifier) but this looks like its causing bugs in the extension hooks. We've just planned an improvement with a bit of a refactor for the next week. We'll work on this task and hopefully do a release to resolve your issues. I'll keep you updated through this post about the progress and walk you through about the improvements we're introducing with the release once we're done. Hope this sounds like a good plan to you 😅
like-gold
like-gold15mo ago
Cool! Thanks for keeping me in the loop. If I can be of help at any time, feel free to drop a message.