Open amoskopp opened 7 years ago
I don't see how this is backwards compatible. A client has to check if a property is an object, but existing clients won't.
@apsoto can you tell me what part of the existing specification or JSON schema specifically disallows using non-strings as values? As far as I know, declaring something as object
only implies that keys have to be strings.
There's isn't anything that disallows non-string values, but existing servers where there are entities with objects as properties this is a breaking change because there was no title
or value
requirement when they were implemented.
If there was a way for clients/servers to negotiate compatible spec versions then this would be compatible.
I understand. This probably means that title
and value
should not be made mandatory. @kevinswiber what are your thoughts regarding human-readable labels for properties?
The purpose of the properties
object is to allow free-form data elements without restriction.
We haven't figured out how to advertise "extensions" yet, but having a title
->value
constraint in properties
would make a good one. I don't see this concept making into the media type specification as-is, given the goal stated above.
@kevinswiber what about media type parameters? Like with audio/ogg; codecs=vorbis
and audio/ogg; codecs=opus
one could advertise the set of extensions used with a specified parameter, like application/siren+json; extensions="properties_title,range_contraints"
.
@kevinswiber But wouldn't anything apart from a simple type like an object be actually an entity? I think as soon as you got a nested structure you can and should give it a name.
@martinotten I've found it useful to have the flexibility to put an array or other simple objects in properties in some cases. If I had to turn those into entities it would be rather burdensome.
I've explore this before on how to annotate data in data that maybe nested—and it's quite difficult. Here are the options I've found.
This would use a special object for defining semantics apart from the actual values, then optionally map those to the properties in the object. I tried this approach here though it's old and wildly incomplete :)
{
"class": ["my-entity"],
"semantics": [
{
"title": "Bar",
"property": "foo.bar"
}
],
"properties": {
"foo": {
"bar": "baz"
}
}
}
This is a little more backwards compatible.
Allow for metadata around properties to be added into a reserved object. Whereas the example above was flat and probably done at the root of an entity, this would be nested inside the property object. JSON-LD does some of this with it's prefixed properties and @context
.
{
"class": ["my-entity"],
"properties": {
"_meta": {
"foo": {
"title": "Foo"
}
},
"foo": "bar"
}
}
We also put together a similar proposal for a more complex implementation for annotating JSON in what we called embedded annotations.
This is backwards compatible only if clients are instructed to ignore properties it does not know about AND they haven't used _meta
.
This is the route this PR takes. The downsides are that you you end up with a magical recursion for handling annotations, and it gets very complicated as you get more nesting in the properties
object. Additionally, it also requires reserved fields because there is no way for a client to know if the presence of title
and value
means it's a title annotating a value, or if it's actual data.
Don't do this with Siren, just use XML :) Basically, if you wanted to, you mimic how XML works. Again, don't do this, however, the current PR is a baby step toward this direction.
{
"nodeType": "string",
"attributes": {
"title": "Foo"
},
"value": "foo"
}
@apsoto Why is that bothersome? This entity wouldn't need its own URI, would it? So moving it to an entity would just mean that you express it in a different structure. It would also have the advantage that you would also define a class you can reuse in another context, like an address.
@martinotten
WRT turning complex property structures into entities is burdensome in that it requires more coding. Likely it's a side effect of the way we serialize our Siren responses. Adding properties are simple one line changes. Adding new entities are typically whole new Classes (as in Java or Ruby classes)
Also, I personally do in fact model entities as an uniquely addressable object (URI). If an entity doesn't have a URI then it's a design smell that it maybe shouldn't really be an entity.
This introduces human-readable titles for entity properties in a backwards-compatible way. Among other advantages, properties with objects as values would enable clients to display labels translated to the HTTP
Accept-Language
.