# Relationships with data: how to manage links and data in the related resources

**URL:** <https://discuss.jsonapi.org/t/relationships-with-data-how-to-manage-links-and-data-in-the-related-resources/2859>\
**Category:** Uncategorized\
**Created:** [June 24, 2024, 9:12am UTC](https://discuss.jsonapi.org/t/relationships-with-data-how-to-manage-links-and-data-in-the-related-resources/2859 "2024-06-24T09:12:42Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![lukas79](https://avatars.discourse-cdn.com/v4/letter/l/9dc877/32.png) [@lukas79](https://discuss.jsonapi.org/u/lukas79)\
**Post date:** [June 24, 2024, 9:12am UTC](https://discuss.jsonapi.org/t/relationships-with-data-how-to-manage-links-and-data-in-the-related-resources/2859/1 "2024-06-24T09:12:43Z")

</div>

Hi!  
Again a question about relationships with data and the related resources.

I’m having some troubles to find a solution for this problem. We have:

- **projects**  
Projects exists on their own, hence we have defined the following endpoints:
  - `projects`
  - `projects/{projectId}`

- **templates**  
Templates exists only within a project. Also we have the following endpoints:
  - `projects/{projectId}/templates`
  - `projects/{projectId}/templates/{templateId}`

- **components**  
Components are also independent entities hence we have:
  - `components`
  - `components/{componentId}`

Each **component** could be assigned to one or more **projects** and, at the same time, be referenced within one or more **templates**. Therefore we have two n:n relationships:

- one between project and component
- the other between template and component

The relationships carry (for now) the position of the **component** within the list of the **components** (for **project** and **template** they could be different). To model this we have therefore defined the following _fictional resources_:

- **templateComponents**  
This resource carries the position of a **component** within a **template**. For this we have:
  - `/projects/{projectId}/templates/{templateId}/templateComponents`
  - `/projects/{projectId}/templates/{templateId}/templateComponents/{templateComponentId}`

- **projectComponents**  
This resource is created to carry the position of a **component** within a **project**. For this we have:
  - `/projects/{projectId}/projectComponents`
  - `/projects/{projectId}/projectComponents/{projectComponentId}`

Having real endpoint for the relationships allows to add/remove and modify the content of them without having to interact with the whole basic resource.

After this premises we could think about the structure of the data shared by each endpoint. To simplify the things, given that project\<-\>component and template\<-\>component are almost the same from now we focus just on the second one.  
Also, without concentrating on **templateComponent** part, our initial drafts are:  
_Project_

```auto
{
   "data":{
      "id":"projectA",
      "type":"project",
      "attributes":{
         "name":"Project A"
      },
      "relationships":{
         "templates":{
            "links":{
               "related":"/project/projectA/templates/template1_A"
            },
            "data":[
               {
                  "id":"template1_A",
                  "type":"template"
               },
               {
                  "id":"template2_A",
                  "type":"template"
               }
            ]
         }
      }
   }
}

```

_Template_

```auto
{
   "data":{
      "id":"template1_A",
      "type":"template",
      "attributes":{
         "name":"Template 1 for project A"
      },
      "relationships":{
         "projects":{
            "links":{
               "related":"/projects/projectA"
            },
            "data":[
               {
                  "id":"projectA",
                  "type":"project"
               }
            ]
         }
      }
   }
}

```

and _Component_

```auto
{
   "data":{
      "id":"componentX",
      "type":"component",
      "attributes":{
         "name":"My first component"
      }
   }
}

```

**TemplateComponent** requires a bit more thinking. The resource itself is just a join table with data between other two tables. It even doesn’t have its own key, but it compose the ones of **template** and **component**. Given that the endpoint is below **project** and **template** and we could always unambiguously identify one part of the composite key (the templateId), to relief the problem to manage a virtual key we opted to model the resource using the id of the **component**. Hence we have:  
_templateComponent_

```auto
{
   "data":{
      "id":"componentX",
      "type":"templateComponent",
      "attributes":{
         "position":"1"
      },
      "relationships":{
         "template":{
            "links":{
               "related":"/project/project1/templates/templateA_1"
            },
            "data":[
               {
                  "id":"templateA_1",
                  "type":"template"
               }
            ]
         },
         "component":{
            "links":{
               "related":"/components/componentX"
            },
            "data":[
               {
                  "id":"componentX",
                  "type":"component"
               }
            ]
         }
      }
   }
}

```

This works good for managing the resource.  
Now we just have to adapt **template** and **component** to integrate this new information. Also, for **template** the things went really smooth. We extend `relationships` with the following and everything is working.

```auto
{
   "data":{
      "id":"template1_A",
      // data omitted
      "relationships":{
      // data omitted
         "templateComponents":{
            "links":{
               "self":"/projects/projectA/templates/template1_A/relationships/templateComponents",
               "related":"/projects/projectA/templates/template1_A/templateComponents"
            },
            "data":[
               {
                  "id":"componentX",
                  "type":"templateComponent"
               }
            ]
         }
      }
   }
}

```

On the other side, for **components** we are faced with some troubles. We can’t just add another field in the relationships field, because each component could be references by several templates. Therefore something like this is not working:

```auto
{
   "data":{
      "id":"componentX",
      "type":"component",
      "attributes":{
         "name":"My first component"
      }
   },
   "relationships":{
      "templateComponents":{
         "links":{
            "self":"/projects/projectA/templates/[templateId???]/relationships/templateComponents/componentX",
            "related":"/projects/projectA/templates/[templateId???]/templateComponents/componentX"
         },
         "data":[
            {
               "id":"componentX",
               "type":"templateComponent"
            }
         ]
      }
   }
}

```

Because the referenced **template** is missing.  
To correctly map the **templateComponent** I would need an array of ids for every template where the component is used, but (from my understanding) this is not possible. I would like to have a url like `/projects/projectA/templates/{templateId}/templateComponents`.

Could it be that I’ve modeled the things in a wrong way? I’ve already thought about other ways to do the things but:

- with a fictional id for **templateComponent** I would face it anyway
- modifying the endpoints and map the resources in a different way I’ve no guarantees that a similar problem would arise in a different form (maybe instead of the path on the query params)

Finally, should I really map all the resources and their relationships in this way?

Could it be that for the **component** the relationship is just with **templates**? This would work, because a link with an array of data is exactly what I have and what I could map. To know more about a component within a template I’ve always to load the template and get the other data from the relationship.

What are your thoughts about this? Could someone help me, please?
