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
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-goldOP•2y 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 😅
hmm I think someone can be help you from @core team
wise-white•2y ago
in tables, you can handle relational data like that: https://refine.dev/docs/api-reference/antd/hooks/table/useTable/#how-can-i-handle-relational-data
useMany
(actually all data hooks) accepts dataProviderName
https://refine.dev/docs/api-reference/core/hooks/data/useMany/#dataprovidernamelike-goldOP•2y 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
.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-goldOP•2y ago
Yes ofc 👍
thank you for your understanding 🚀
judicial-coral•2y 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:
But the buggy thing is, the inference of the resource from the route should be working even without the identifier
value 🤔
I'll check thislike-goldOP•2y 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.judicial-coral•2y ago
You can pass it with the
resource
propertylike-goldOP•2y 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-resourcejudicial-coral•2y 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 issuelike-goldOP•2y 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/4432wise-white•2y 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-goldOP•2y ago
Thanks for the example @alicanerdurmaz ! The
createButtonProps={{ resource: 'my-identifier' }}
on the List component did the job for me.judicial-coral•2y 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-goldOP•2y ago
Cool! Thanks for keeping me in the loop. If I can be of help at any time, feel free to drop a message.