Open kr opened 7 years ago
For convenience, here's the main point:
Appendix B. Analysis
The primary problem with the "X-" convention is that unstandardized
parameters have a tendency to leak into the protected space of
standardized parameters, thus introducing the need for migration from
the "X-" name to a standardized name. Migration, in turn, introduces
interoperability issues (and sometimes security issues) because older
implementations will support only the "X-" name and newer
implementations might support only the standardized name. To
preserve interoperability, newer implementations simply support the
"X-" name forever, which means that the unstandardized name has
become a de facto standard (thus obviating the need for segregation
of the name space into standardized and unstandardized areas in the
first place).
For example, a hypothetical alternate version of the ‘Extensions’ section might have said:
Publishers can use custom objects in JSON Feeds. Any names that aren't described on this page are custom. Custom objects can appear anywhere in a feed.
…
It’s good practice to name an extension with a company or service name, to provide a clue right away as to what it’s for and who made it. However, if your custom object is useful to most people who read and write feeds, consider the possibility that it might end up becoming a de facto standard whether you want it to or not. If that seems likely, choose a suitably general name.
This could also be solved by introducing a new top-level object: extra
. It might look like this:
{
"extra": {
"my_vendor": {
"some_key": "value"
}
}
}
This extra
object would obviously be optional.
Thanks @kr and @svenluijten. Good to know about RFC 6648. I lean toward keeping _
because it reads cleanly compared to extra nesting, and is obvious what is not part of the specification, but I don't think I mind extensions that use generic names. For example, in Micro.blog I decided to use _microblog
because the extra fields could just as easily be part of a different service. (We debated a few other more unique choices like reverse-DNS strings, etc. but they added a lot of clutter to the format.)
A popular extension will become a de-facto standard. This has happened many times on the web (apple-touch-icon, meta viewport, tons of -webkit-*
CSS supported cross-browser, XFF HTTP header, etc.).
The HTML standard ended up using a central registry for this (https://wiki.whatwg.org/wiki/MetaExtensions) with a very low bar for registration of new names, and it seems to work fine.
So I'd suggest just asking people to coordinate. Decentralized zero-contact extensibility sounds nice, but in reality we can talk to each other, especially that extensions will require cooperation between feed creators and consumers anyway.
Given the history of RSS extensions coordination seems too hard. Following RFC 6648 gives you something like this:
"https://blueshed-podcasts.com/json-feed-extension": {
"explicit": false,
"copyright": "1948 by George Orwell",
"owner": "Big Brother and the Holding Company",
"subtitle": "All shouting, all the time. Double. Plus. Good."
}
Possible spec text:
Of course the developer behind the extension spec can and will go out of business and will delete the docs like so much of RSS extension documents did. But if one or more extensions in the same subject space get's popular and is useful for the whole ecosystem like the podcasting extensions to RSS, I'd argue that it is the job of the spec to document those extension instead of leaving the subject open to different extensions by different sources which all can go under.
AFAIK RSS did not event attempt to have any sort of central coordination. There was no registry. 2.0 spec didn't even have a clear way to provide feedback.
They've just said to use XML namespaces, and XML namespaces were generally misunderstood and incorrectly implemented (e.g. Sparkle required a specific prefix name instead of using NS URLs).
URL keys are longer, much harder to remember and easier to get wrong (was it http or https? trailing slash?).
And they're solving problem of decentralized extensibility with zero contact, instead of the problem of "we're all going to have to use this weird key if this extension becomes de-facto standard".
Let's say message stickers become the new rage and somehow every podcast will have to have a sticker pack. We could have:
_sticker
key. Maybe there will be one proprietary format from the first-mover, or a few competing ones clashing, either by accident or because they disliked the first proprietary one.
same as above, but with addition of _sticker2
, and _better_sticker
, so every feed will end up having all three just in case.
_vendor-name-sticker
, and everyone will forever use the vendor's name for the key, even after the vendor goes out of business. It will either be added to the official spec ("all _
-prefixed keys are extensions, except _vendor-name-sticker
, which is totally standard now!), or it won't be in the spec, and everyone will have to reverse-engineer it or find an alternative "spec" on some forum or StackOverflow answer.
http://json.feed.vendor.com/ns/extensions/sticker/1.0
, same mess as above, just longer to type, and some people will get confused why it doesn't work when they "correct" the URL to https.
OR a sticker
key! If the spec asks people to make a github issue, then the first person to attempt implementation will get it. Maybe they will even get a feedback on the format, and other implementors will find it to cooperate instead of duplicate. And later it could be added to the official spec without any legacy mess carried over.
I think @pornel's examples highlight why we went with _sticker
. All extension styles have downsides, so best to go with the one that is the most simple and readable. I've seen a few extensions in the wild already, and they don't overwhelm the document. (If an extension becomes widely used, makes sense to file a request to incorporate it into the spec.)
Going with just sticker
would have been (as far as I can tell) the most simple and readable, even more so than _sticker
. No centralized registry is necessary. Same spec, same guidelines, same everything else, just… no underscore.
If an extension becomes widely used, makes sense to file a request to incorporate it into the spec.
Yes! The interesting part is what happens then?
There's a popular extension called _sticker
. Everyone loves it and agrees it should be put in the spec, but there's lots of software out in the wild that supports only the underscore-name. You can't change the name because that would fail to interoperate with existing software (remember Rule #1). You can't standardize the existing name because the spec explicitly promises never to specify underscore-names, even in the future. What do you do?
It's similar to what happens with CSS extensions, e.g. -webkit-opacity
. If it's incorporated into the official spec, people use both for a little while, then eventually we forget about the extension and just use the standard name. It's not perfect, but I think it's better than the conflicts that could happen if there's no prefix on extensions.
Yeah, so with CSS, basically only web browsers can add extensions. (Because they're the only software that interprets CSS that people have to interact with over the network.) And they basically only do this when they're trying to get their extension into the standard. And even then it only works because almost all browsers have aggressive auto-update systems. Everyone who's writing CSS files knows this from the start, so they plan for it and it's less of a headache. (But still a big headache that takes years to resolve for each extension.)
The current situation strikes me as more similar to HTTP header fields. The classic example is X-Forwarded-For. There's a Forwarded field in the HTTP RFC, but nobody uses it. Everybody still uses X-Forwarded-For because that's the one that works. With X-Frame-Options (https://tools.ietf.org/html/rfc7034), they realized it would be futile to try to rename it and didn't even bother, they just standardized the X name.
The difference is, with CSS there are basically only five programs in the world you need to worry about, and they auto-update like nobody's business. With HTTP there are hundreds, and many of them are pretty conservative (i.e. slow or never) with updates.
I think JSON feed (especially if it is successful — and I really hope it will be! I love this spec, should've said so to start with) will be more on the HTTP end of the spectrum. As a machine-readable and machine-writable format, it'll have various network services that generate, transform, and interpret it. A feed aggregator is one example. If there is a widely used extension, say, _forwarded_for
, that shows the URLs of the upstream feeds, you'll never manage to rename it to forwarded_for
even if you want to.
You can specify the new name, but everyone will just keep using the name that is generated by the feed server on their random free multi-tenant web host and still works even on their cousin's five-year-old PC.
In short: I predict the _
prefix will make things more complicated.
the conflicts that could happen if there's no prefix on extensions
I don't totally follow here. Do you have an example of a conflict that would happen with no prefix on extensions, and that would be prevented by putting an underscore in front?
Note that new nonstandard HTTP header fields (these days) don't use any prefix (e.g. DNT), and conflicts are not a problem in practice.
Good points. You're right that CSS is not the best comparison, although it's still similar in that I think the most popular extensions will be proposed by feed readers.
As for conflicts, let's imagine that sticker
in one extension contains a pair of string values (maybe full_url
and thumbnail_url
), and in another extension is an object with different members (maybe type
, size
, and url
). It's true that the conflict is there whether the field has an underscore prefix or not. But the problem gets worse if there's no prefix, because if we bring one version of the extension into the spec, and new feed readers adopt it, those feed readers will be surprised when they encounter the same field name with a completely different structure underneath it.
In this scenario it actually becomes difficult to even check whether a feed is valid. As soon as we promoted an extension with a conflicting name like that into the spec, we'd actually invalidate other feeds that used to be perfectly fine (the sticker
extension that used the thumbnail_url
value, for example, when the spec now says it must be an object with 3 different required members). The prefix should prevent that from happening.
As @sonicdoe pointed out in another issue, extensions have to be objects, so my sticker
example above was originally too much of a simplification. I've edited it to fix this. I think the point is the same either way. Thanks!
The situation with one key having two different bodies in two different implementations may happen indeed, but I think it's not too bad for two reasons: a) it can be made less likely, b) even if it happens, it can be resolved.
It can be made less likely by tracking what extensions are used in the wild, and asking people to propose/register extensions they use. It is in implementors' interest to have their extensions widely known, conflict-free, and compatible with other clients.
And even when a conflict happens, it can be fixed:
"url"
is the right key, but use "full_url"
as a fallback). This works even when one side is uncooperative.Aha, I see. Yeah, of course I can't say that such a conflict wouldn't happen. (But as @pornel mentioned it's in everyone's interest to avoid conflicts, so they seem unlikely. This matches what's happened so far with HTTP.)
In that unfortunate scenario, I agree the spec wouldn't want pick just one of the two sticker
extensions to standardize. I think a reasonable thing to do would be to use a new name such as badge
or stickie
or whatever. Then this problem reduces to the same problem as with _
prefixes, except now it only happens when there is actually a conflict.
But I appreciate that all that might end up still being a confusing situation. Thanks for hearing me out.
Reading, it says the prefix applies to new objects, not necessarily extra and established properties inside an existing object. For example, I just added a syndication property to items based on alternate copies of it. This isn't an object.
From RFC 6648 ‘Deprecating the "X-" Prefix and Similar Constructs in Application Protocols’:
This spec's
_
prefix seems to qualify as a "similar construct".Maybe it's too late to do anything about this, and even if not, maybe the arguments in that RFC are not persuasive enough. But I wanted to raise the issue anyway, just in case.