Identifying a specific entity, relative to the parent entity

159 views
Skip to first unread message

Gabriel Castillo

unread,
Apr 9, 2013, 12:30:50 AM4/9/13
to siren-hy...@googlegroups.com
Currently, I don't see a defined, distinct way of navigating to a specific entity from the parent entity.

While you can use an entity's "class" property to filter down to one or more entities it can not be relied on to be unique.  One option I have played around with is using the first rel from the rels array, however, it does feel funny doing it this way and I don't have much real experience with api's to know if this is a good practice.

Should there be an optional "name" property on nested entities?

Gabriel Castillo

unread,
Apr 9, 2013, 12:41:02 AM4/9/13
to siren-hy...@googlegroups.com
I should add that in case the rel value is a url, I'm doing hacky stuff like stripping out all characters before the last `/`

Kevin Swiber

unread,
Apr 9, 2013, 5:38:35 AM4/9/13
to siren-hy...@googlegroups.com
Hey Gabriel,

The way I do this is by filtering on one or more of: sub-entity rel value, sub-entity class, and sub-entity properties.

Trust boundaries can also be established by link relation documentation. Sometimes it's a rule in the API documentation that an entity of a particular link relation may only contain sub-entities of another particular link relation. In such a case, filtering sub-entities by link relation is more of a validation that the server is acting as promised.

If you need to pull a specific named entity from an existing response, I would filter on a "name" property in the "properties" object of each of the sub-entities.

If this is client-guided and a network call is acceptable, I might offer a filter in the API (GET /ostriches?name=Petey). Of course, this filter can also be exposed as an action on the parent entity itself.

Let me know if I just created more questions than answers. :)

--
Kevin Swiber
@kevinswiber
https://github.com/kevinswiber

Alex Soto

unread,
Apr 9, 2013, 2:56:42 PM4/9/13
to siren-hy...@googlegroups.com
Siren provides the relational constructs to enable finding sub-entities, but what your asking for seems more like a 'function' to find a sub-entity based on some unique identifier.

I think if you need to pick out sub-entity of type X where the parent entity has many sub-entities of the same type, then as Kevin mentioned, you walk the list and filter/find the one that matches the sub-entity you are interested in.

This assumes you know the what to look for ahead of time.  If you don't then maybe there should be a property on the parent entity that provides the distinct property value(s) of the sub-entity.

Another idea is to use the class attribute of the sub-entity to mark the 'important' one, but that still means you are walking the sub-entities and filtering it yourself.






--
You received this message because you are subscribed to the Google Groups "Siren Hypermedia" group.
To unsubscribe from this group and stop receiving emails from it, send an email to siren-hypermed...@googlegroups.com.
To post to this group, send email to siren-hy...@googlegroups.com.

Gabriel Castillo

unread,
Apr 10, 2013, 4:43:40 PM4/10/13
to siren-hy...@googlegroups.com
The option to filter is quite useful (filtering by rel seems like it could be a bit weird considering they will likely be urls), however, I'm still left with no way to key off of entities, the way I can key off of properties and actions.

Using a name property inside the properties object won't work since its very likely I will have (and do have) a property on some old legacy object already called "name".

In the end the only thing that is making sense to me for my use-case which is to be able to key the entity (and doesn't involve me doing hacky stuff like using the first rel and stripping off everything before the last "/") is having having a "name" property on all sub-entity objects.  It will so happen that in all my cases, that name will be a 1:1 nearly 100% of the time with the rel (I don't currently have entities with more than one rel)

I'm still shaky on this but I'll see how that works out and I think Siren allows for adding extra properties on entity objects so I think I can get by and still claim to be Siren :)




--
You received this message because you are subscribed to a topic in the Google Groups "Siren Hypermedia" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/siren-hypermedia/s3Ya8peQOfo/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to siren-hypermed...@googlegroups.com.

Kevin Swiber

unread,
Apr 12, 2013, 10:12:58 PM4/12/13
to siren-hy...@googlegroups.com
FYI: There is more discussion on this happening here: https://github.com/kiva/backbone.siren/pull/15

On the API Craft mailing list, Jon Moore mentioned how his mobile team found a need for anchors in the API.  Put in that context, this started making a lot more sense to me.  The benefits could be pretty cool.

To copy/paste from the above-linked GitHub Pull Request, here are some initial thoughts on syntax.  I'm open to changing this.  This is just a first pass.

{
  "class": ["order"],
  "properties": {
    "total": 55.50,
    "itemCount": 3,
    "saleItems": ["#ginger-bread-penguins", "#pickled-puppets"]
  },
  "entities": [
    {
      "class": ["order-item"],
      "name": "ginger-bread-penguins",
      "rel": ["http://rels.x.io/order-item"],
      "properties": { "id": 12345, "name": "Ginger Bread Penguins", "price": 17.50, "quantity": 1 },
      "links": [
        { "rel": ["self"] "href": "http://api.x.io/order-items/12345" }
      ]
    },
    {
      "class": ["order-item"],
      "name": "pickled-puppets",
      "rel": ["http://rels.x.io/order-item"],
      "properties": { "id": 12346, "name": "Pickled Puppets", "price": 37.99, "quantity": 1 },
      "links": [
        { "rel": ["self"] "href": "http://api.x.io/order-items/12346" }
      ]
    },
    {
      "class": ["order-item"],
      "name": "clearance-mitten",
      "rel": ["http://rels.x.io/order-item"],
      "properties": { "id": 12347, "name": "Clearance Mitten", "price": 0.01, "quantity": 1 },
      "links": [
        { "rel": ["self"] "href": "http://api.x.io/order-items/12347" }
      ]
    }
  ],
  "links": [
    { "rel": ["self"], "href": "http://api.x.io/orders/34829cde3f" }
  ]
}
The saleItems array contains links (hashes) to the in-document sub-entities, identified by the new name property.

This allows for interesting links.  What happens when this is followed:  http://api.x.io/orders/34829cde3f#pickled-puppets ?

Linking to a sub-entity in a certain context is potentially very powerful (or dangerous).  Happy to hear any thoughts.

-- 
Kevin Swiber
@kevinswiber

On Apr 9, 2013, at 12:30 AM, Gabriel Castillo <gab...@uglymunky.com> wrote:

--
You received this message because you are subscribed to the Google Groups "Siren Hypermedia" group.
To unsubscribe from this group and stop receiving emails from it, send an email to siren-hypermed...@googlegroups.com.
To post to this group, send email to siren-hy...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/siren-hypermedia/-/K9XjERyBhK4J.

Alex Soto

unread,
Apr 13, 2013, 2:42:07 AM4/13/13
to siren-hy...@googlegroups.com
I cross posted this up on github as well.
----

WRT having an entity locator name:

In my API I want to be able to cache as much as possible so I'd like to minimize the differences between resource representations between the entity and sub-entity representations.  This would allow me to re-use an entity's representation when it's also a sub-entity.

I also would like the use of some name to facilitate sub-entity lookups on the client. However I'd prefer to keep from adding on more top level properties ('name'), especially ones that only exist in sub-entities (currently, 'rel' is the only other one) to assist server-side caching.

I'm an URN newbie, but after reading up on it, the urn: sytnax you proposed seems like a valid use of URNs.  Since 'rel' is already an array, API's can add additional metadata in the future without needing changes to the Siren spec.  However, would this start to bastardize the intent of 'rel'?  Is 'class' a more appropriate place for this metadata?

WRT the use of the #hash in the url:
I've been toying with a way to optimize API calls by specifying a sub-entity path in the URL so a client can grab a bunch of resources that might otherwise require a number of API calls.  I'm not sure if it was what you intended, but it clicked in my head as similar.

For example:
Entity X has Sub Entity Y which contains Sub Entity Z

A simple request for Entity X (/entity/X), returns the response with Sub-entity Y as an entity link.

However, if you requested /entity/X#Y.Z you would get a response with a full representation of sub-entity Y and sub-entity Y would contain a full entity representation of Z.

If that's what you meant by using a url fragment, it might warrant a separate thread to discuss that and leave this thread's topic as what to name an entity for lookup purposes.
Message has been deleted

Gabriel Castillo

unread,
Dec 30, 2013, 6:15:21 PM12/30/13
to siren-hy...@googlegroups.com
wrt to the syntax @Kevin posted above for Siren, what are the thoughts around making the entities array [optionally] be an entities object:

"entities": {
"ginger-bread-penguins": {
"class": ["order-item"],
"properties": { "id": 12345, "name": "Ginger Bread Penguins", "price": 17.50, "quantity": 1 },
"links": [
{ "rel": ["self"] "href": "http://api.x.io/order-items/12345" }
]
},
"pickled-puppets": {
"class": ["order-item"],
"properties": { "id": 12346, "name": "Pickled Puppets", "price": 37.99, "quantity": 1 },
"links": [
{ "rel": ["self"] "href": "http://api.x.io/order-items/12346" }
]
}
}

Not having names for entities was a major point of contention between myself and others on my team when considering the use of Siren.  They didn't see the need to have a top level "entities" property and felt everything should just be inside the "properties" property.  While I see the need to split them out, I do think we lose the very real need to locate sub-entities.  

My proposal is to keep sub-entities in the "entities" property but to have it be an object instead of an array.  I feel that all solutions proposed so far are just work-arounds for this.

This change would address a few things:

1 - provides a way to uniquely identify a sub-entity so that you can locate it
2 - does not require an additional top level property (e.g. "name", as pointed out by @Alex) 
3 - the entity can remain unchanged regardless of wether its an "entity" or "sub-entity" (pointed out by @Alex)
4 - It keeps us from using things like the properties, links, or rel to handle what I think should be a first-class "citizen" of the spec

The primary reason I see for keeping it as optional:
1 - backwards compatible
2 - Collections work best if entities is an array


Gabriel Castillo

unread,
Feb 3, 2014, 6:54:37 PM2/3/14
to siren-hy...@googlegroups.com
Sorry, I hope I'm not going too far away from the spirit of the spec with this request :) But I do think that this is a critical piece that needs to be addressed.  With that said...

Yet another option would be to keep "entities" as an array, and have each array item be an object with the following attributes:

- name - The name of the sub-entity
- rel - The relationship of the sub-entity to the parent entity
- [optional] entity - The actual entity
- [optional] href - The url for the entity (only necessary if this is a linked-entity)

Its slightly more verbose but the benefit is that it completely leaves the entity, itself, untouched, thus you can always expect it to look the same, wether its nested or not.

Ultimately, the key use-case is always to be able to reference an entity of an object like you would a property of an object (eg, parentEntity.childEntity).  Any thoughts before I make a pull request?

Alex Soto

unread,
Feb 3, 2014, 10:58:50 PM2/3/14
to siren-hy...@googlegroups.com
So far, I haven't come across the need to programmatically pick out a specific sub-entity 'by name'.  It's always been 'by type'.  So a combination of rel and class has been sufficient for me.

When a user 'chooses' a specific entity, it's by some UI interaction, and in that case, the sub-entities' URI (self link) or an ID property is known, so it can be 'found' quite easily.

Can you explain your use case some more so I can get a clearer understanding?  For example, why do you need to programmatically access the 'penguins' instead of just accessing it as a generic 'order-item' ?

Gabriel Castillo

unread,
Feb 4, 2014, 1:48:10 AM2/4/14
to siren-hy...@googlegroups.com
Hmm...I think I used a bad example :)

A better example might be a user entity that has "contactRecord", "account", and "purchases" sub-entities:

User
name: 'Bob'
, age: 34
, joined: 123456
, id: 123456
, contactRecord: {} 
, account: {}
, purchases: []
When we put this into Siren format, we differentiate between a "sub-entity" and a "property" but as a consumer I shouldn't have to care about this differentiation.  I just want the contactRecord (user.contactRecord), or the account (user.account), or the purchases (user.purchases).  I also shouldn't be too coupled to the concept of "type", especially if it can be avoided.

Only by having a name, can I be absolutely sure that there is a strict "has one" relationship with the contactRecord, or account, or puchases sub-entity.  Filtering by a combination of rel and class does not provide this.

I think that the "user" example works better than the "order-items" in that the previous one was more like a collection.  I don't think collection items need names; its perfectly fine to have them indexed.

Alex Soto

unread,
Feb 4, 2014, 2:47:49 AM2/4/14
to siren-hy...@googlegroups.com
Take with a grain of salt, but this is how I would take what I've implemented so far and apply to your example:

Siren doesn't explicitly provide has-one, has-many semantics, but I've implied them by how many entities of that 'rel' are provided.  Not a great answer, but that's how I've been mapping things.

It seems like you are also interested in having convenient property-like access for an entity.  I would say that's the siren client/lib's responsibility to provide the syntactic sugar.

Here's how I would map it to use 'rel'.  A little more verbose, but it would look like this in psuedo-ish code:

user.entities.where({rel:'contact-record'})
user.entities.where({rel:'account'})
user.entities.where({rel:'purchases'})
Reply all
Reply to author
Forward
0 new messages