Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On the Nature of Rels #16

Open
smizell opened this issue Jul 15, 2016 · 5 comments
Open

On the Nature of Rels #16

smizell opened this issue Jul 15, 2016 · 5 comments

Comments

@smizell
Copy link

smizell commented Jul 15, 2016

There is one small detail that I have been unable to unify in my head. In some
(many) cases, my head is to blame for this inability, but every once in a while
something is actually a tad off. I add this disclaimer so that everyone feels
totally free in telling me I'm crazy when they reach the end. Of course this
can be true no matter the outcome of this note.

Ion Object and HREF

Let's start with the Ion object. An Ion object by definition has a meta
member. You can add an href member as an "IRI location of the resource" (as
defined in section 6.1).

{
  "meta": { "href": "https://example.io/users/1" },
  "firstName": "Bob",
  "lastName": "Smith",
  "birthDate": "1980-01-23"
}

For one, is there any implied link relation here, such as self? Second, if I
were to add a self link relation here, would this link relation be from
the current resource?

As per the spec, it appears that an Ion object with an href is also an Ion
link. And here, the rels for the Ion link are related from itself to another
resource.

Ion Link

Now let's check out an Ion link.

{
  "meta": { "href": "http://example.io/foo" },
  "user": {
    "meta": { "href": "https://example.io/users/1", "rels": ["user"] },
    "firstName": "Bob",
    "lastName": "Smith",
    "birthDate": "1980-01-23"
  }
}

I have added an explicit link relation of user here. But for the user link,
the link relation is from the root Ion object to the Ion link. This is a
different pattern than with the first example.

Ion Collections

Another example is how the collection link relation is used. It is a slightly
different than the previous two examples. To recap, the first link relation
appears to relate from itself to another resource. The second appears to relate
from the parent object to the link.

With an Ion collection, the collection relation determines the nature of the
object itself. It is not necessarily a link from itself to a resource or some
self or canonical link. It is rather defines how the object should be
handled, which is slightly different than a normal Ion object.

Why does this even matter, Stephen?

Good question! Hopefully I can put some value to my ramblings.

First, if a link relation acts differently depending on if it's nested or not,
then you can run into some strange situations where you nest an existing
resource with some incorrect link relations.

Take this for example:

{
  "meta": { "href": "https://example.io/users/1", "rels": ["self"] },
  "firstName": "Bob",
  "lastName": "Smith",
  "birthDate": "1980-01-23"
}

And embed it in some other object, as shown here:

{
  "meta": { "href": "http://example.io/foo" },
  "user": {
    "meta": { "href": "https://example.io/users/1", "rels": ["self"] },
    "firstName": "Bob",
    "lastName": "Smith",
    "birthDate": "1980-01-23"
  }
}

Here you see the nature of link relation changes. I hope that makes sense :)

The collection link relation is another one that has additional meaning. When a
Ion collection is embedded into another Ion object, the rels defines both the
relation and the nature of the collection itself. This may also not be an
issue, but I bring this one up mostly to show the ways that rels works
depending on the context.

Final Observation

As a final note, to think out loud, it is almost as if an Ion object that is
the root object should not have an href, and should rather use a self link
relation (or related relation).

I am not sure I have any recommendation for the Ion collection and what to do
about the rels there. This may be necessary thing. My point is that, in the
case where the Ion collection is the root object, the link relation is used in
a way that does not fit with how Ion links work.

@lhazlewood
Copy link
Member

lhazlewood commented Jul 15, 2016

Hi @smizell!

Just a minor note - it is rel not rels even though the value is always a JSON array.

As to your question, did you get a chance to read the spec's section on Link Relation Types? I could be mistaken, but that section - I think - addresses your questions on what link relations exist.

For example, assume the following document from your example:

{
  "meta": { "href": "http://example.io/foo" },
  "user": {
    "meta": { "href": "https://example.io/users/1", "rels": ["user"] },
    "firstName": "Bob",
    "lastName": "Smith",
    "birthDate": "1980-01-23"
  }
}

The meta.href value has an implicit link relation of self based on the linked spec. The user.meta object doesn't need to specify "rel": ["user"] member because user is already an implicit link relation since the containing object uses user as the member name. Of course you could explicitly set it, but it's redundant.

Does this make sense/answer your questions?

Cheers!

@fosrias
Copy link

fosrias commented Jul 21, 2016

So, as I look at this discussion, unless I am mistaken, meta object in a json object with an href MUST implicitly imply self. It may imply another implicit type as follows the following are equivalent:

{
  "meta": { "href": "http://example.io/foo" },
  "user": {
    "meta": { "href": "https://example.io/users/1", "rel": ["user"] },
    "firstName": "Bob",
    "lastName": "Smith",
    "birthDate": "1980-01-23"
  }
}
{
  "meta": { "href": "http://example.io/foo" },
  "user": {
    "meta": { "href": "https://example.io/users/1", "rel": ["self", "user"] },
    "firstName": "Bob",
    "lastName": "Smith",
    "birthDate": "1980-01-23"
  }
}
{
  "meta": { "href": "http://example.io/foo" },
  "user": {
    "meta": { "href": "https://example.io/users/1", "rel": ["self"] },
    "firstName": "Bob",
    "lastName": "Smith",
    "birthDate": "1980-01-23"
  }
}
{
  "meta": { "href": "http://example.io/foo" },
  "user": {
    "meta": { "href": "https://example.io/users/1" },
    "firstName": "Bob",
    "lastName": "Smith",
    "birthDate": "1980-01-23"
  }
}

Some wording may be necessary to clarify, but I think in principle this should be true. A link in an Ion Object in top-level should have a relation to itself as self.

Ok. So, as I write these examples, I think I now see @smizell's point. The rel of an embedded ion object should be the relation to the parent object. Hm. This is interesting from a transclusion standpoint, which is what I think the point is.

It may warrant some wording to clarify that self in an embedded ion object relation is solely a relationship to itself and not the parent object for completeness. @smizell Is that what you are pointing out (Frankenhilbert mind at work again to see this nuance)?

@smizell
Copy link
Author

smizell commented Jul 22, 2016

Mark, yes, I think you're following me here. I do think what you said that "the rel of an embedded ion object should be the relation to the parent object" is most of my struggle here, but also some of the magic around href and meta in the root object.

For example, the root object has the implied self, but when transcluded, it loses that link implied relation. Also, as a root object, the rel relates to itself (see the Ion Collection and implied self), but this changes when it is linked within another resource. This feels off to me for something that has so much power around transculding resources.

This also means—as I think you're mentioning Mark—there is no way to explicitly use the rel in a linked resource for a self link. You would have to do something like:

{
  "meta": { "href": "http://example.com/bar" },
  "foo": {
    "meta": { "href": "http://example.com/foo" },
    "self": {
      "meta": {
        "href": "http://example.com/foo"
      }
    }
  }
}

Not that it is bad to do that, but just saying there is a difference here.


In all of this, I think my internal struggles boil down to the href and rel being used explicitly or implicitly for a resource itself as a root object. They make sense to me when used as a link, but it takes on a more magical role when it becomes a root object.

Beware: thinking out loud here. I'm wondering if the root object should not use meta for anything. From the spec, it appears you don't have to use the collection rel to make something a collection object—it's just the presence of items. What does an Ion collection get you over a normal collection object?

Also, you can alleviate the self issue if you remove the implicit self and require people to use a normal self link. Can you include links if something is not an Ion Object?

Hope that all makes sense!

@smizell
Copy link
Author

smizell commented Jul 22, 2016

Also, as a side note Mark, I wanted to comment on your examples. As @lhazlewood mentioned, the implicit self relation is defined in the spec, however, the self relation is not there for linked objects.

(I missed this, thanks for clarifying, Les)

@davidsowerby
Copy link

@smizell

In all of this, I think my internal struggles boil down to the href and rel being used explicitly or implicitly for a resource itself as a root object. They make sense to me when used as a link, but it takes on a more magical role when it becomes a root object.

There seems also to be an implication that the meta.href in the root can ONLY be a reference to self - at least that is what I think the spec is saying, and does make sense.

If that is the case, then assuming that self is implied, then meta.rel should be ignored or disallowed? Or are there cases where other meta.rel values in the root object would be meaningful?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants