ietf-wg-httpapi / rfc7807bis

Revision of RFC7807: HTTP Problem Details
Other
20 stars 8 forks source link

"*" names for new members are not going to work in XML #74

Closed dret closed 1 year ago

dret commented 1 year ago

These two paragraphs read a little funny in conjunction, given that the first one announces that the spec may start using names that are against the guidance in the second paragraph.

Future updates to this specification might define additional members that are available to all problem types, distinguished by a name starting with "". To avoid conflicts, extension member names SHOULD NOT start with the "" character.When creating extensions, problem type authors should choose their names carefully.

To be used in the XML format (see Appendix B), they will need to conform to the Name rule in Section 2.3 of [XML].

I have no great idea how to improve this, but reading through the text just made me wonder how these two things fit together and others may have the same reaction.

mnot commented 1 year ago

Huh.

mnot commented 1 year ago

After a bit of discussion, I think we've landed on std- -- thoughts?

darrelmiller commented 1 year ago

Many programming languages don't support hyphen as a character in identifiers. Using std_ would require less translation as all the languages I have seen do support underscore. Having said that, most serializers/deserializers already have the ability to do mappings between wire formats and types so it is not a big deal.

ndw commented 1 year ago

You're defining the format. I think you can do better. Don't invent a new mechanism. If you have the will to do it in a proper, extensible fashion, borrow a page from XML or JSON-LD and work out how to associate URIs with short names in some way. If you don't have the will to do that, borrow a page from HTML5 and reserve all names that don't include a hypen (or an underscore or 💩) in them for yourself and let anyone adding new properties distinguish theirs.

benbucksch commented 1 year ago

reserve all names that don't include a hyp[h]en ... in them for yourself and let anyone adding new properties distinguish theirs [by using a hyphen]

I like that suggestion. Standard fields should be easy and straight-forward (including future ones). Non-standard fields should do a little extra.

mnot commented 1 year ago

If we were doing this from scratch, that might be workable (although it's not very intuitive). As it is, we have to take reasonable steps to assure we won't collide with existing usage; that is very likely to.

martinthomson commented 1 year ago

So, the opposite of "X-" then? I find myself wondering whether this solution is worse than the problem it aims to fix.

Let's say that I include a field that encodes an entire problem report from an upstream server. I define "upstream" to carry the problem report. That turns out to be useful and it is standardized as "std-upstream"[^1]. Now, do I teach my code to just strip "std-" prefixes? Maybe not for one instance like this, but if that starts happening more often, it starts looking tempting and "std-" becomes meaningless.

The alternative is just to suck it up and acknowledge that there might be collisions between what a standard defines and what a resource uses. New additions to standards might conflict with resource-specific usage that is unaware of changes in standards. But problem reports are always subject to some amount of interpretation and subtle semantic differences in the interpretation of fields with the same name but different definitions is already possible for stuff defined outside of standards. Reifying standardized values doesn't really improve that situation a whole lot.

As @mnot says, with forethought, this problem might have been anticipated and avoided.

[^1]: More likely it would a different name because standards, but maybe I was lucky this time and no one decided to bikeshed names.

andrecedik commented 1 year ago

I'm torn between all of the proposed solutions. I can totally understand the arguments for/against each and every one of them. In the end, what matters is that the solution is usable and understandable for all parties involved.

I do have to agree with @martinthomson and would like to pick up his example. If std-upstream gets introduced we would have elements in the returned JSON that have the prefix attached to them and some that don't. From a users perspective this feels odd. So it probably would make sense to also "claim" the prefixed version for the old elements (std-status, std-instance, std-type, and so on).

The second option would be to define that API providers who use their own elements prefix them with x- or make them use a hyphen like @ndw proposed. This would make it also easier for consumers who are not familiar with the spec to understand what has been added by the provider. Yes this would also "break" existing implementations, but at least API providers only have to adjust their work once, instead of doing it every time a new "standard element" gets introduced.

The third option would be to create a new (version of the) standard replacing this one and in there define extensibility the way we think it should be implemented. Of course this would mean postponing a solution for providing future extensions for quite some time, but at least then we don't have to fear that we're breaking existing implementations.

mnot commented 1 year ago

There are many ways to spell this; e.g., if we want a new standard extension foo that takes integer values from conflicting with a type-local extension that takes (for example) string values, we could put standard extensions in a container:

{
 "type": "https://example.com/probs/out-of-credit",
 "title": "You do not have enough credit.",
 "detail": "Your current balance is 30, but that costs 50.",
 "instance": "/account/12345/msgs/abc",
 "std-exts": {
     "foo": 1
  },
  "foo": "abc"
}

Or, we could invert that, and recommend that future problem types put everything into a local-exts container:

{
 "type": "https://example.com/probs/out-of-credit",
 "title": "You do not have enough credit.",
 "detail": "Your current balance is 30, but that costs 50.",
 "instance": "/account/12345/msgs/abc",
 "foo": 1,
 "local-exts": {
     "foo": "abc"
  }
}

However, that doesn't avoid the problem that @martinthomson points out -- someone using a type-local extension that gets promoted to a standard extension needs to transition.

Maybe it's not that bad. If I'm consuming an existing problem type that uses the local extension, I'll need to understand that extension to consume it; it merely being defined as a standard extension doesn't change that. The producer of the problem can rely upon that, and can choose to either add the standard extension as a backwards-compatible change to their API, or they can wait until they version the API to switch to the standard, as a breaking change.

asbjornu commented 1 year ago

The producer of the problem can rely upon that, and can choose to either add the standard extension as a backwards-compatible change to their API, or they can wait until they version the API to switch to the standard, as a breaking change.

That holds true if the producer has complete control over how the problem+json is produced. As https://github.com/ietf-wg-httpapi/rfc7807bis/pull/48#issuecomment-1256130831 proves, various web application frameworks such as Microsoft ASP.NET may be the deciding factor in what is included in the response, and how.

As an upgrade from one version of a framework to another may rest on many other factors than its problem+json implementation, there's reasons to believe future extensions to the standard implemented in such frameworks may cause unintentional breakage.

mnot commented 1 year ago

So, AIUI you're saying that if a framework adds a new standard member and a deployment upgrades to it without versioning their API, trouble could result. Fair.

Stepping back, the purpose of *- (or whatever we call it) was to make room for future standard extensions; we don't have one to include at the moment. Since it appears we're not sure how best to accommodate them, it might be best not to try to accommodate them -- i.e., punt the issue down the road -- especially since the right solution might be to introduce a new media type.

martinthomson commented 1 year ago

I'm supportive of that conclusion. This has escaped and thus we no longer have any control over it. Though a new media type is a bit disruptive, it seems commensurate with the risks.

dret commented 1 year ago

On Apr 12, 2023, at 08:02, Mark Nottingham @.***> wrote:

Stepping back, the purpose of *- (or whatever we call it) was to make room for future standard extensions; we don't have one to include at the moment. Since it appears we're not sure how best to accommodate them, it might be best not to try to accommodate them -- i.e., punt the issue down the road -- especially since the right solution might be to introduce a new media type.

i my mind let's keep punting. we didn't address it in the original RFC and it may just be one of those things where the cure is worse than the disease.

asbjornu commented 1 year ago

I too support postponing this decision until the need to add another standard field arises.

darrelmiller commented 1 year ago

Without chair hat, I support the removal of the extension.

darrelmiller commented 1 year ago

Resolved https://github.com/ietf-wg-httpapi/rfc7807bis/commit/3da190e90144589fa06bc31186cd9f6adbb71259