passive-yellow
passive-yellow4h ago

How do I deal with nested resources?

I have a resource for users, and I want to be able to add and remove tags from said users; how do I use the useCreate and useDelete hooks for those?
5 Replies
kapa.ai
kapa.ai4h ago
Hi @khadhulu. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To handle nested resources like adding and removing tags for users in refine, you should: 1. Define your nested resource paths in your resource definitions, using route parameters for dynamic segments (e.g., /users/:userId/tags). This allows you to represent the relationship between users and their tags. 2. Use the useCreate and useDelete hooks with the appropriate resource path, including the user ID in the path. You can extract the user ID from the route parameters using the useParsed hook. Example: Adding a Tag to a User Suppose your API endpoint for adding a tag to a user is POST /users/:userId/tags. You can use useCreate like this:
import { useCreate, useParsed } from "@refinedev/core";

export const AddTagButton = () => {
const { userId } = useParsed(); // Extract userId from the route

const { mutate } = useCreate({
resource: `users/${userId}/tags`,
});

return (
<button
onClick={() => {
mutate({
values: { name: "new-tag" }, // Replace with your tag data
});
}}
>
Add Tag
</button>
);
};
import { useCreate, useParsed } from "@refinedev/core";

export const AddTagButton = () => {
const { userId } = useParsed(); // Extract userId from the route

const { mutate } = useCreate({
resource: `users/${userId}/tags`,
});

return (
<button
onClick={() => {
mutate({
values: { name: "new-tag" }, // Replace with your tag data
});
}}
>
Add Tag
</button>
);
};
This approach is confirmed in refine's official guidance for nested resource creation, where you use the dynamic part of the URL in the resource parameter and extract the ID from the route using useParsed How should I structure dataProvider and resources for nested API structures?. Example: Removing a Tag from a User If your API endpoint for removing a tag is DELETE /users/:userId/tags/:tagId, use useDelete as follows:
import { useDelete, useParsed } from "@refinedev/core";

export const RemoveTagButton = ({ tagId }) => {
const { userId } = useParsed();

const { mutate } = useDelete();
return (
<button
onClick={() => {
mutate({
resource: `users/${userId}/tags`,
id: tagId,
});
}}
>
Remove Tag
</button>
);
};
import { useDelete, useParsed } from "@refinedev/core";

export const RemoveTagButton = ({ tagId }) => {
const { userId } = useParsed();

const { mutate } = useDelete();
return (
<button
onClick={() => {
mutate({
resource: `users/${userId}/tags`,
id: tagId,
});
}}
>
Remove Tag
</button>
);
};
This pattern is also supported by refine's data hooks, which allow you to specify the full resource path including nested parameters useCreate documentation, useDelete documentation. Key Points - Use route parameters (e.g., :userId) in your resource paths. - Extract dynamic values from the route using useParsed. - Pass the full nested resource path to the hooks. This approach is flexible and works for any nested resource scenario in refine, as confirmed by both documentation and community discussions How should I structure dataProvider and resources for nested API structures?, Github Issue: Nested resources. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4h ago
<@236239059184386048> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
passive-yellow
passive-yellowOP4h ago
@kapa.ai how can I add those to my resources?
kapa.ai
kapa.ai4h ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- To add nested resources like user tags to your resources in refine, you should define them in the resources array with the appropriate nested paths using route parameters. For example, if you want to manage tags for users, you can define a resource for tags nested under users like this:
resources={[
{
name: "users",
list: "/users",
show: "/users/:userId",
// ...other actions
},
{
name: "user-tags",
list: "/users/:userId/tags",
create: "/users/:userId/tags/create",
edit: "/users/:userId/tags/:tagId/edit",
show: "/users/:userId/tags/:tagId",
meta: {
parent: "users",
},
},
]}
resources={[
{
name: "users",
list: "/users",
show: "/users/:userId",
// ...other actions
},
{
name: "user-tags",
list: "/users/:userId/tags",
create: "/users/:userId/tags/create",
edit: "/users/:userId/tags/:tagId/edit",
show: "/users/:userId/tags/:tagId",
meta: {
parent: "users",
},
},
]}
- The list, create, edit, and show properties use route parameters (e.g., :userId, :tagId) to represent the nested structure. - The meta.parent property helps organize the resource hierarchy in the UI and breadcrumbs, as recommended in refine's official answers and documentation How should I structure dataProvider and resources for nested API structures?. You can then use these resource definitions in your routes and hooks. The dynamic parameters (like userId) will be available in your components via hooks such as useParsed or useResourceParams. This approach is supported and recommended for nested and multi-tenant structures in refine Migration Guide: resources, Core <Refine> resources. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4h ago
<@236239059184386048> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?