# Type in attributes

**URL:** <https://discuss.jsonapi.org/t/type-in-attributes/1123>\
**Category:** Uncategorized\
**Created:** [October 8, 2017, 1:16pm UTC](https://discuss.jsonapi.org/t/type-in-attributes/1123 "2017-10-08T13:16:24Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![a-komarev](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/a-komarev/32/440_2.png) [@a-komarev](https://discuss.jsonapi.org/u/a-komarev)\
**Post date:** [October 8, 2017, 1:16pm UTC](https://discuss.jsonapi.org/t/type-in-attributes/1123/1 "2017-10-08T13:16:24Z")

</div>

Accordingly to the spec [Fields section](http://jsonapi.org/format/#document-resource-object-fields):

> resource can not have an attribute and relationship with the same name, nor can it have an attribute or relationship named type or id.

But what to do if model has type attribute. For example:

```
{
    "data": {
        "id": "1",
        "type": "score",
        "attributes": {
            "amount": 10,
            "type": "quality"
        }
    }
}

```

---

<div class="post-metadata">

**Author:** ![michaelhibay](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/michaelhibay/32/405_2.png) [@michaelhibay](https://discuss.jsonapi.org/u/michaelhibay)\
**Post date:** [October 9, 2017, 1:13pm UTC](https://discuss.jsonapi.org/t/type-in-attributes/1123/2 "2017-10-09T13:13:04Z")

</div>

Change the model. If you absolutely must \_type is a good way, but from a semantic standpoint there may be a less generalized name to use instead.

---

<div class="post-metadata">

**Author:** ![a-komarev](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/a-komarev/32/440_2.png) [@a-komarev](https://discuss.jsonapi.org/u/a-komarev)\
**Post date:** [October 9, 2017, 10:41pm UTC](https://discuss.jsonapi.org/t/type-in-attributes/1123/3 "2017-10-09T22:41:19Z")

</div>

Thank you for the reply.

Is there any restrictions to have `type` key in nested attribute json object?

```
{
    "data": {
        "id": "1",
        "type": "something",
        "attributes": {
            "blabla": "bloblo",
            "wage": {
                "system": "time-rate",
                "type": "hourly",
                "amount": "50",
            }
        }
    }
}
```

---

<div class="post-metadata">

**Author:** ![michaelhibay](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/michaelhibay/32/405_2.png) [@michaelhibay](https://discuss.jsonapi.org/u/michaelhibay)\
**Post date:** [October 10, 2017, 3:05am UTC](https://discuss.jsonapi.org/t/type-in-attributes/1123/4 "2017-10-10T03:05:34Z")

</div>

There isn’t any restrictions in that direction as the type/id restriction is set to establish the reserved word in the key space for the fields. Since that wouldn’t be a key for the field, it wouldn’t pose a problem. However, two things to keep in mind is it wouldn’t be a great idea to nest the field just to be able to get around the rule. The other note I generally like to give is that complex attribute fields are far more often than not resources in their own right and would be better served in your design as related resources.

---

<div class="post-metadata">

**Author:** ![a-komarev](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/a-komarev/32/440_2.png) [@a-komarev](https://discuss.jsonapi.org/u/a-komarev)\
**Post date:** [October 10, 2017, 7:40pm UTC](https://discuss.jsonapi.org/t/type-in-attributes/1123/5 "2017-10-10T19:40:06Z")

</div>

When I’m facing situation like that I’m always starting to think that it would be better to split everything to relationships because it will be easier to extend app functionality later, it’s cheaper to find related resources by IDs than by string values, but on the other side I’m starting to think that I’m making very complicated API which will be hard to work with.

For example with wage another one approach was to split complex attribute to many relationships.

`GET /jobs/1?include=wage.currency,wage.system,wage.unit`

```
{
  "data": {
    "type": "job",
    "id": "1",
    "relationships": {
      "wage": {
        "data": {
          "type": "wage",
          "id": "2"
        }
      }
    }
  },
  "included": [
    {
      "type": "wage",
      "id": "2",
      "attributes": {
        "rate": "300"
      },
      "relationships": {
        "currency": {
          "data": {
            "type": "currency",
            "id": "31"
          },
          "system": {
            "data": {
              "type": "wage-system",
              "id": "4"
            }
          },
          "unit": {
            "data": {
              "type": "wage-unit",
              "id": "5"
            }
          }
        }
      }
    },
    {
      "type": "currency",
      "id": "31",
      "attributes": {
        "code": "USD"
      }
    },
    {
      "type": "wage-system",
      "id": "4",
      "attributes": {
        "name": "time-based"
      }
    },
    {
      "type": "wage-unit",
      "id": "5",
      "attributes": {
        "name": "hourly"
      },
      "relationships": {
        "system": {
          "data": {
            "type": "wage-system",
            "id": "4"
          }
        }
      }
    }
  ]
}

```

But wouldn’t it be harder for developers to work with it?

With complex attribute it will look like this:

`GET /jobs/1`

```
{
  "data": {
    "type": "job",
    "id": "1",
    "attributes": {
      "wage": {
        "system": "time-based",
        "unit": "hourly",
        "currency_code": "USD",
        "rate": 300
      }
    }
  }
}

```

What questions should developer to ask to clearly understand is it complex attribute or relationships?

_Sorry for that off-topic question, but it’s rasing every time I’m trying to find the right word not so common as type: “Maybe it’s better to create one more relationship with it’s own type instead of introducing complex attribute?”._

---

<div class="post-metadata">

**Author:** ![michaelhibay](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/michaelhibay/32/405_2.png) [@michaelhibay](https://discuss.jsonapi.org/u/michaelhibay)\
**Post date:** [October 10, 2017, 9:10pm UTC](https://discuss.jsonapi.org/t/type-in-attributes/1123/6 "2017-10-10T21:10:28Z")

</div>

As a designer you have the freedom to chose the format and the default included relationships. So if you have a natural grouping of relationships 3 or 4 deep which would be beneficial to send as the default, you are in control until the caller includes sparse fieldset or include query parameters.

I have no idea how you got to your first design, it’s redundant, and honestly not good which, you correctly state, offers a poor DX. The later example however, is easily handled in a relationship and I am at a loss to figure out the part you don’t grasp yet.

```auto
{
  "data": {
    "type": "job",
    "id": "1",
    "attributes":{
      "name":"First Job"
    },
    "relationships": {
      "compensation": {
        "links":{
          "self":"https://example.org/api/job/1/relationships/compensation",
          "related":"https://example.org/api/wages/5"
        },
        "data":{
          "type":"wage",
          "id":"5"
        }
      }
    },
    "included":[
      {
        "type":"wage",
        "id":"5",
        "attributes":{
          "system": "time-based",
          "unit": "hourly",
          "currency_code": "USD",
          "rate": 300
        }
      }
    ]
  }
}

```

The question I ask is very simple, does the complex type make sense in it’s own context? Or does it require the context of the parent resource to make sense? Using your wage resource example modified as above, the wage _IS_ a complete concept. However, if you wanted to simply have a resource “rate”, this would require more context in order for it to make sense.

I hope that helps!

---

<div class="post-metadata">

**Author:** ![a-komarev](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/a-komarev/32/440_2.png) [@a-komarev](https://discuss.jsonapi.org/u/a-komarev)\
**Post date:** [October 10, 2017, 9:55pm UTC](https://discuss.jsonapi.org/t/type-in-attributes/1123/7 "2017-10-10T21:55:53Z")

</div>

Thank you for pointing out idea about default relationships until `include` query parameters will appear, I’ve never thought about this way. I’ve always thought that `include` query param should always append to defaults, and not overwrite them.

Accordingly your example, I didn’t understand why there is no `data` key in your `wage` relationship and doesn’t have `type` and `id`, isn’t it a requirement? And isn’t relationship’s `attributes` should be placed in `included` section?

I’ve thought that only this way is appropriate by the specs:

```auto
{
  "data": {
    "type": "job",
    "id": "1",
    "attributes":{
      "name":"First Job"
    },
    "relationships": {
      "wage": {
        "data": {
          "type": "wage",
          "id": "2"
        }
      }
    }
  },
  "included": [
    {
      "type": "wage",
      "id": "2",
      "attributes": {
        "system": "time-based",
        "unit": "hourly",
        "currency_code": "USD",
        "rate": 300
      }
    }
  ]
}

```

---

<div class="post-metadata">

**Author:** ![michaelhibay](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/michaelhibay/32/405_2.png) [@michaelhibay](https://discuss.jsonapi.org/u/michaelhibay)\
**Post date:** [October 11, 2017, 1:36am UTC](https://discuss.jsonapi.org/t/type-in-attributes/1123/8 "2017-10-11T01:36:41Z")

</div>

I apologize for the confusion, I was rushed trying to post my answer to you before I had to leave work at the end of the day.

You are 100% correct the relationship field should have a resource identifier object, in addition to links for self and hopefully other relevant things too. In my haste I simply moved the wage complex type to demonstrate the concept.

I’ll go back and fix it to reduce any future confusion, but clearly you understand the structure just fine. 😃

---

<div class="post-metadata">

**Author:** ![a-komarev](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/a-komarev/32/440_2.png) [@a-komarev](https://discuss.jsonapi.org/u/a-komarev)\
**Post date:** [October 11, 2017, 1:48am UTC](https://discuss.jsonapi.org/t/type-in-attributes/1123/9 "2017-10-11T01:48:10Z")

</div>

Nothing wrong. I just was scared that I’ve missed something huge in json:api and was in hope that you will say: “it’s just a concept” :} Thank you for the clarification!

---

<div class="post-metadata">

**Author:** ![a-komarev](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/a-komarev/32/440_2.png) [@a-komarev](https://discuss.jsonapi.org/u/a-komarev)\
**Post date:** [October 11, 2017, 2:03am UTC](https://discuss.jsonapi.org/t/type-in-attributes/1123/10 "2017-10-11T02:03:03Z")

</div>

You have asked:

> I have no idea how you got to your first design

Thats easy. I’m always asking myself a question, is this entity (relationship) could exist without parent entity and will have zero-level endpoint to get it and all it’s relations?

- if NO - I’m transforming it to complex attribute.
- If YES - I’m keeping it as relationship.

For example if `wage` will be a relationship for the job, then I will have zero-level `GET /wage` endpoint in my API for sure. I was always thought like that. Such a complicated example was born because each of these entities has zero-level endpoints: `/wage-systems`, `/wage-units`, `/currencies`.

On the other example, if there will be requirement to add `job-position` to the job I’d prefer to have it as relationship because I will 100% sure there will be `/job-position/{id}?include=jobs` endpoint which return a list of jobs related to this position.

---

<div class="post-metadata">

**Author:** ![michaelhibay](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/michaelhibay/32/405_2.png) [@michaelhibay](https://discuss.jsonapi.org/u/michaelhibay)\
**Post date:** [October 11, 2017, 3:18am UTC](https://discuss.jsonapi.org/t/type-in-attributes/1123/11 "2017-10-11T03:18:01Z")

</div>

Yes the devil’s advocate design approach is always there, you could in fact build any API you ever wanted with `/resource` and `/char/[0,1]` endpoints. As a computer scientist it’s tempting to think that way, but that road generally leads to premature optimization in a BIG way.

To tackle this problem I often speak of domain value in deciding where to draw the line between a dependent complex attribute and a related resource. From a high level perspective I generally aim to have the semantics of the domain drive my initial pass, and then I look closer for the point where the value of the context becomes _more_ than the sum of the attributes. For example, you could create a `/rate` resource, but that would mostly just amount to an enumeration of some natural numbers, but add enough pieces together, and a `/wage` resource now has conceptual value beyond the sum of its parts. You may find my blog on [hypermedia API design](https://wp.me/p8LJoU-q) and other API related posts helpful.

I _do_ highly advise a shallow resource design, or ‘zero-level’ endpoints. A primary reason for this is to maintain the simplest API design possible, and a shallower design is more likely to lead to opportunities for design consolidation. In your example, you aim for higher specificity at the ‘zero-level’ where I would advise generalizations, with semantic distinctions via message structure meaning a generally defined resource, sending a specific type message.

As for your last paragraph, I think you intended something more like this.

```auto
/job-position?filter[job]=5

```

A couple of points on this, jsonapi requires relationship links to be accessible which guarantees a bidirectional reference capability between the two resources through `/.../relationships` endpoints on the primary resource. The secondary resource has the filter parameter on a query for the resource collection, as I included above. The second point is reinforcing my previous statement about overly specific resources in your ‘zero-level’ designs. Always remember Postel’s Law “be liberal in what you accept, and conservative in what you send”, and using overly specific resource design does the opposite.

---

<div class="post-metadata">

**Author:** ![a-komarev](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/a-komarev/32/440_2.png) [@a-komarev](https://discuss.jsonapi.org/u/a-komarev)\
**Post date:** [October 11, 2017, 12:54pm UTC](https://discuss.jsonapi.org/t/type-in-attributes/1123/12 "2017-10-11T12:54:32Z")

</div>

I’ve read your blog earlier, it’s really huge work and I’ve learned a lot from it. Especially about content negotiation and versioning.

> [@michaelhibay](#):
>
> As for your last paragraph, I think you intended something more like this.
> 
> /job-position?filter[job]=5

Not sure that it’s will be exact what I want to do. Maybe because I’ve used wrong word for example. Lets say job-position == profession. And I want to have:

- List of all Jobs: `/jobs`
- Dictionary of all Professions: `/professions`
- Detailed info about one Profession: `/professions/{professionId}`
- Detailed info about one Profession with jobs which related to it: `/professions/{professionId}?include=jobs`

So if I’ve understood you right to get jobs filtered for profession it’s better to use:

```auto
/jobs?filter[profession]={professionId}

```

But if I need to get Profession with all it’s relationships I need to use:

```auto
/professions/{professionId}?include=jobs,candidates,rel3,rel4

```

---

<div class="post-metadata">

**Author:** ![michaelhibay](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/michaelhibay/32/405_2.png) [@michaelhibay](https://discuss.jsonapi.org/u/michaelhibay)\
**Post date:** [October 11, 2017, 2:20pm UTC](https://discuss.jsonapi.org/t/type-in-attributes/1123/13 "2017-10-11T14:20:16Z")

</div>

As I understand the example you have provided, this is the same concern to be addressed as the tag and blog post example.

To clarify my understanding, when I read dictionary of all professions I interpreted this as ‘collection’ and not as an enumeration.

As an API designer, the json:api spec gives you the latitude to determine if the implicit target relationship is included in the relationships link collection or not. My previous post described the scenario where you wouldn’t want to include this link, and therefor would need to retrieve the items via a backreference query. Imagine a resource which has relationships to 50 other resources, the response to a query of the relationships collection would become very large if all the relationships were included. If only 10 of those relationships originate from this resource, it would be intuitive to include only those in the collection. As I said, you have the latitude to make these decisions as there is no hard rules around the representations you build.

Given the domain and or semantic need to reference described in your post, and in the similar tag / blog-post examples, it would be a good idea for it to be included in the relationship collection itself. The resulting query to the profession resource would be something like this:

```auto
/professions/{profession_id}/relationships/jobs

```

Data shaping via the ‘include’, ‘fields’, and pagination parameters is really unrelated to the discussion of the reference, which is only concerned about directing to the appropriate resource.

Another point to make clear, I am _not_ advocating path driven semantics in these posts, I am simply using the commonly understood example format from the spec to demonstrate the concepts clearly.

From a learning perspective I think it would be worth your time to go back and read the specification again with a focus on understanding the purpose of the ‘include’ and ‘fields’ query parameters. Much of the power of the json:api format stems from the processing of these parameters. They are very nuanced and you consistently have been showing ‘include’ in your examples when your stated goals are solved by a ‘filter’ operation.

Finally, thank you for the kind words on my work. It was my intent from the beginning to help others understand these topics more clearly, and it’s very rewarding to know it has been helpful.

---

<div class="post-metadata">

**Author:** ![a-komarev](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/a-komarev/32/440_2.png) [@a-komarev](https://discuss.jsonapi.org/u/a-komarev)\
**Post date:** [October 11, 2017, 8:41pm UTC](https://discuss.jsonapi.org/t/type-in-attributes/1123/14 "2017-10-11T20:41:24Z")

</div>

By Profession Dictionary I meant document with collection of resources:

```json
{
  "data": [
    {
      "type": "profession",
      "id": "1",
      "attributes": {
        "name": "Carpenter",
      }
    },
    {
      "type": "profession",
      "id": "2",
      "attributes": {
        "name": "Tailor"
      }
    }
  ]
}

```

Thank you so much for all your feedback. I’ve revised all my decisions about API design and clearly see that `filter[relationship]` parameters will simplify it and will prevent duplicated endpoints, ease code maintaining and decrease amount of tests need to be done.

`/jobs?filter[profession]={professionId}` just replaced `/professions/{professionId]/jobs` and now I have only 1 endpoint. Same for another similar cases.

---

<div class="post-metadata">

**Author:** ![michaelhibay](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/michaelhibay/32/405_2.png) [@michaelhibay](https://discuss.jsonapi.org/u/michaelhibay)\
**Post date:** [October 12, 2017, 1:48pm UTC](https://discuss.jsonapi.org/t/type-in-attributes/1123/15 "2017-10-12T13:48:30Z")

</div>

I’m glad I was able to help, good luck!
