RFC 5988 Conformance
Closed this issue · 18 comments
Needs to address:
- Conforming relation names as json keys
- rel attribute in meta
- custom link relation types including multiple (rel)
- using profiles to define relation name like ALPS.
- when IANA registered rels.
Basically, address using keys as a 'relation name' that defaults to 'relation type' in supported cases. Otherwise, use rel in meta.
Agreed, the reference (linking) section needs to codify this clearly.
Additionally, I think I want to stop referring these to 'links' and instead formalize them as 'references'.
The reason is that when expansion comes into play, it's not a normal 'link' anymore - at least not in the way that most people think of links.
I think the word 'reference' better represents its design: it is a reference to another resource. If expanded, the reference is 'materialized', if not expanded, the reference isn't materialized. Most people don't think of links as being 'materializable', whereas references can often be thought of that way (ActiveRecord, Hibernate, lazy-loading, etc).
@lhazlewood My initial musings are as follows:
- I think
relations
is probably a more technically accurate term in web sense and I think is probably closer to the meaning thanreferences
. We can materialize a relation per se. Or we can exercise the related resource to do something, e.g. IANAedit
relation type, where the related resource performs the edit. - I see the meta object being much more than a link. It is a related resource and that resource may do tasks rather than just return data. I think this is something really cool we can do in Ion. More on that in the threads on uniform interface methods and forms.
- As such, we can then call the key of JSON objects that contain a meta object a
relation name
. These relation names can be IANA relation types in which case therelation name
is also therelation type
orrel
. If therelation name
is not IANA registered, either you have arel
attribute in the meta object that is 5988 conforming or use a profile like ALPS to specify the custom relation type tied to therelation name
. Thus, the JSON key replaces adding aname
attribute in the meta object, like HAL has, for example, and is human-friendly and intuitive. We don't want to use URIs or curies as keys IMO, the way HAL does. Rather, we use a full onrel
if we need it in a meta object. - We should add a
rel
attribute to the meta object regardless and allow space separated rels. I think it should default toself
for the top-level meta object in aninstance resource
.
@fosrias One thought on this:
We should add a rel attribute to the meta object regardless and allow space separated rels.
I would think it would be better if the rel
was always an array. In your client, if you are separating on spaces, it means that you always have to split on spaces in case there may be more than one rel. Starting it as arrays means there is no extra processing needed to parse the rel.
@fosrias I was thinking about 'relation' vs 'reference' today for Ion taxonomy as relation
never really sat well with me. I think I can properly verbalize my thoughts now:
A link ('reference') is a pointer/syntactical representation of an association from one resource to another. An (IANA) relation (rel
) indicates the purpose or meaning of the relationship, but the relation is not the reference itself.
For example, consider the following:
<a href="https://api.example.com/users" rel="collection">Users</a>
The anchor XML element is itself the link (or as I'm calling it, the reference). The rel
attribute represents the relation, or meaning/purpose of link.
Now a parallel in Ion:
"users": {
"meta": { "href": "https://api.example.com/users", "rel": ["collection"] }
}
The same is true here: the above JSON example shows a syntax for a reference (and with expansion, you can have a materialized reference, etc). The relation is (still) the meaning or purpose of the link. In Ion, the relation can be implicit (the JSON field name) or explicit (a rel
meta attribute), but the actual JSON structure is still a link/reference.
So when I say reference in Ion, I'm talking about the JSON name/object-value pair format/structure. When I say relation, I'm talking about the semantic meaning/purpose of the reference.
Does this make sense?
Yes. Makes sense. So, what you are grappling with is what to call the actual object and that relation
does not capture that. Yeah I can see that. One of the comments as I was ramping up a team on hypermedia by one of my more critical engineers was he did not like all the "hypermedia mumbo-jumbo" as he put it when a normal developer would call it one thing but hypermedia community another.
What I have taken from that is that ideally, we don't introduce new terms or concepts unnecessarily. So, part of my suggestion of relation
was that it is an existing idea. However, it really does not pass the litmus test of being a common concept to the average dev, but it is a good web concept.
That being said, part of my resistance to reference
is that it introduces a new term that to me needs some explaining and thus the question of whether it is the best term. So, to me we should do our best to introduce terms that get the most bang for their buck. So, in HAL there is a resource object
. To me that is a useful and simple term that has connotations related to what the media-type is related to.
I think in ion our challenge is that we have a resource object that morphs from being a link to being a materialized resource or embedded resource or possibly a resource that performs an action, but we don't want to make the distinction with different elements (that is meta accommodates it all).
I am not convinced yet that reference
is the best concept for that, and thus my own hesitation or postulated alternative when you brought it up. Frankly, I could go with a resource object
and another concept that differentiates the collapsed vs. expanded version. This however is a bit limiting when the relation is more of an action than a reference.
Maybe we have a 'ion object' that is indicated by the presence of a meta tag. It is either a:
- link (unexpanded, link only)
- resource (includes all data)
- partial (includes partial data)
- action
Not completely satisfied with the above. I know @smizell will have some thoughts on this. So, I am rambling but not coming to a conclusion here. Maybe more just expanding the background for the discussion, I hope.
Good thoughts. @smizell Please chime in.
Sorry for the long delay here. I took a short sabbatical away from computers then was out of town, so just now catching up!
This is somewhat of my personal struggle for me with using JSON keys for data instead of structure. The only real reason I can see JSON keys being useful in hypermedia messages is to make it easy to interact directly with the JSON message itself. For instance, if I have this (as from above):
{
"users": {
"meta": { "href": "https://api.example.com/users", "rel": ["collection"] }
}
}
I can simply do users.meta.rel
with the parsed JSON to get the rel and it's very simple. My issue is, I don't believe a user should ever interact directly with the JSON message. If this is true, then having users
as a key provides me with no added benefit. I could just as easily have done:
{
"links": [
{
"rel": ["collection"],
"reference": "users",
"href": "/users"
}
]
}
This would have conveyed the same information, while also requiring me to define what a reference actually is. At that point, as @fosrias has said, we've introduced a new concept to the hypermedia world. In this example, it feels like this users
is a link relation, just one that is not defined anywhere.
BUT, if keys are going to be used, as in Ion's case, what is this key? Here are the ideas I see:
- It MAY be an IANA link relation
- It MAY be a link relation defined in a profile, such as an ALPS profile
- In the event it is not an IANA relation, not in an ALPS document, and is not a URL for a custom link relation, what is it?
Maybe Ion Object is general enough to not introduce a new concept, while providing a blanket, Ion-specific term for it. An Ion Object can be many different types of hypermedia objects depending on what is in meta
. Ion Reference could work too, so long as it's not really a new hypermedia concept.
Lots of thinking out loud here! Please pick apart :)
Coming back to this:
I can simply do users.meta.rel with the parsed JSON to get the rel and it's very simple.
Or users.meta.href
(which would be very useful when writing web frameworks or JavaScript frameworks for example).
I agree with you that not interacting with the raw JSON is a good idea, especially when references (links) and materialized references (as I call them) are involved. It is probably not desirable (IMO) to require a a JS application developer to have to worry about the details of 'is this a link? If so, let me go execute a request, otherwise, I'll treat it as a full object'.
Stormpath's Node.js SDK takes the approach of not exposing the raw JSON - resources returned to the app developer are actually wrapper or 'proxy' objects that delegate to the raw JSON structure, but provide many convenience methods so application developers don't have to worry about link resolution, caching, and other things. The design is really nice and offers an implementation buffer between the server and the app developer (i.e. if raw resource structure changes, the app dev is largely shielded from it - they just have to upgrade the client library dependency).
Anyway, as far as naming goes, I'd be fine w/ 'Ion Object' actually. IMO, an 'Ion Object' is basically a JSON object that has an immediate child meta
name/value pair.
An 'Ion Object' can be further classified as a link (if it has only a meta
name/value pair and no other fields) or an Ion Resource (materialized) - easy.
So, I just realized we kind of went off tangent a little bit for taxonomy (which is fine!). I think we can close this issue out per the original ticket description if we codify the how linking (and link relations) are specified or implied.
I'll create a pull request with doc edits so you can see how they apply and we can discuss edits in the PR before merging. I'll also enumerate the logic/algorithm here as bullet points for discussion.
@lhazlewood So, I have thought, w/r to the spec on a basic level that there are two objects that we should define:
Ion Object
- Any object that contains ameta
member.Meta Object
- The value of ameta
member.
I think if the spec initially defines those 2 objects then most of the spec will really just be defining the Meta Object
. Thoughts?
To extend on what @fosrias said, it would be good to also define the different kinds of Ion Objects. In other words:
- An Ion Object without a method or with a GET method along with a non-templated HREF is a safe, idempotent transition.
- An Ion Object without a method or with a GET method along with a templated HREF and template parameters is a URI template
So on...
These rules will be helpful in defining how a client interacts with each object, as these different kinds of objects will require different kinds of client processing.
Just some added thoughts!
This might be a little more readable than the PR if it helps: https://github.com/ionwg/ion-doc/blob/links/draft-ion.adoc
@lhazlewood Like the direction. Have some questions and comments that I will bring up on the PR when you open it.
The initial PR is now ready for review.
Because of the change 'noise', I encourage you to read the rendered document first:
http://ionwg.github.io/draft-ion.html
And then perhaps add in-line comments here: https://github.com/ionwg/ion-doc/pull/10/files
(or comments to this issue thread is fine too - whatever you prefer).
Also, I completed #12 today, so any commit or merge to the ion-doc
repo's master
branch will automatically publish a new rendered version of the document to that URL.
@lhazlewood In Prague wrapping up a bunch of stuff this week. Back in SF next week and have more time to dig into this, FYI.
@fosrias sounds good - looking forward to your feedback.
@fosrias and @smizell I'm closing this out now. The last remaining concerns around media types are handled w/ produces
and accepts
and @smizell's suggestions for clarifying idempotent transitions were added as well. Please see the new method
meta member in the registry.
If you feel like this should be re-opened, that's totally fine, please feel free to do so or open a new ticket if desired.