ietf-wg-httpapi / rfc7807bis

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

Shouldn't parameters be semicolon-separated? #56

Closed awwright closed 1 year ago

awwright commented 1 year ago

Over in https://mailarchive.ietf.org/arch/msg/httpapi/GRGrz_dh4ccwB696uYR21_6brU8/ I noted that it's odd that parameters are separated by commas, because in other contexts this is semantically the same as the same header repeated multiple times.

It doesn't make sense that

Problem: type="https://example.net/problems/almost-out"
Problem: title="you're almost out of credit"
Problem: credit_left=20

should be the same as

Problem: type="https://example.net/problems/almost-out", title="you're almost out of credit", credit_left=20

... This is a problem because if an intermediary appends a Problem header to a response that already contains a Problem header; the problem in the resulting message would become mangled.

I suggested using the syntax of the Link header, which is already well established and could easily be re-used, something like:

Problem: <https://example.net/problems/almost-out>; title="you're almost out of credit”; credit_left=20

This syntax has an exact representation as regular expression.

Or sf-item:

Problem: "https://example.net/problems/almost-out"; title="you're almost out of credit”; credit_left=20

I don't think I got much of a formal response so I'd like to ask here.

mnot commented 1 year ago

Hey @awwright - sorry you didn't get a response earlier.

There can only be one problem in a response, which is why we chose this representation -- it's the most direct mapping from the data structure (as a Dictionary).

You're right that an intermediary adding a problem will mangle it, we should address that as a LC comment. However, the fix is not to allow multiple problems in the syntax; it's to warn intermediaries against doing that.

And please, please don't use a regex to parse structured fields -- there's no need, many implementations are available.

awwright commented 1 year ago

If re-using Link is out of the question, then wouldn't sf-item be most appropriate? That seems to support all the same features, and would be clear that more than one Problem field is invalid.

I only bring up regex because since compliance is a concern, and since every (non-recursive) ABNF has an exact representation as a regex, you can avoid the need to use any hand-written parser (including structured fields). But this doesn't seem very widespread and hopefully I can share more on this later.

mnot commented 1 year ago

The nice thing about using Dictionary is that it mirrors the dictionary-based format of a Problem in JSON.

Using Item would have the effect of more visibily breaking if someone erroneously added another Problem header. I'm not sure I like the implicit type as the item, but am not hugely against it.

Anyone else have an opinion? @dret @sdatgit ?

sdatspun2 commented 1 year ago

The nice thing about using Dictionary is that it mirrors the dictionary-based format of a Problem in JSON. I'm not sure I like the implicit type as the item

+1 on both.

Honestly, I have yet to come across a need to convey problem details via a header in HTTP APIs yet. APIs that would send problem details in header should not send any problem details in message content and vice a versa. Nothing wrong technically but two different parsers, etc. hurts dev experience. I have been to places where different groups of the same enterprise send errors in message content using different schemas, just because they cannot agree on a single schema or they want innovation or etc. Imagine how difficult it would be for developers writing apps consuming those APIs.

awwright commented 1 year ago

The nice thing about using Dictionary is that it mirrors the dictionary-based format of a Problem in JSON.

I think the key difference is the sf-dictionary is an open map (the set may be incomplete, and additional items can be added at any time), and a JSON object is closed (the set is exhaustive). Whereas with sf-item, once properties on an item are defined, they cannot be expanded. This open behavior of sf-dictionary may be reasonable in many places, but I don't think it is here.

Honestly, I have yet to come across a need to convey problem details via a header in HTTP APIs yet

I see two big uses:

(1) Web browsers might be able to act on the headers in a way not feasible for the response body, or the server wants to return a machine-readable error and an HTML response; and

(2) it can be used to better specify the nature of generic x00 statuses; making a superior alternative to minting your own status codes: Instead of people unilaterally minting cutesy status codes like "420 Enhance Your Calm", this would encourage responses like "400 Client Error" with Problem: "http://example.com/errors/enhance-your-calm"

mnot commented 1 year ago

I think the key difference is the sf-dictionary is an open map (the set may be incomplete, and additional items can be added at any time), and a JSON object is closed (the set is exhaustive). Whereas with sf-item, once properties on an item are defined, they cannot be expanded. This open behavior of sf-dictionary may be reasonable in many places, but I don't think it is here.

That's a very minor difference; adding two types to both forms is invalid; it's just that they'll be handled in different ways. I don't see that as making a big difference, though (e.g., to debugging).

awwright commented 1 year ago

That's a very minor difference; adding two types to both forms is invalid

Does either Problem or Structured Fields say that a repeated key would be an error? I can't find anything on this, and it hasn't occurred to me to check for repeated keys or how I should handle those (ignore the whole Problem field? Ignore the duplicate key only?).

I agree the likelihood of an error is low, but to paraphrase my earlier argument, if purpose of using Structured Fields is highly robust parsing (among other benefits), then the definition of Problem should probably be robust against gateways that append headers, too.

As I'm reading, one more thing to address is that a Dictionary implicitly exists even when there's no members:

As with Lists, an empty Dictionary is represented by omitting the entire field. This implies that fields defined as Dictionaries have a default empty value.

I'm not sure this poses a problem as such—but to me it's just more intuitive to say if there's no Items in the sf-item then there's no Problem, and if there's one item, then that is the Problem.


I'd like to make one last pitch, I've seen more than a couple people now question the benefit of the Problem header, and I really appreciate how it can extend generic status codes, so I think this should be described better:

HTTP/1.1 400 Client Error
Problem: "http://example.com/errors/enhance-your-calm"

Notice how using the sf-item form emphasizes that interpretations of the extension members depend on the problem type, and how this saves a few bytes for the most common case.

awwright commented 1 year ago

adding two types to both forms is invalid

Actually, can you please elaborate on this? Most JSON implementations will ignore the earlier properties, and Structured Fields requires this specifically:

Note that when duplicate Dictionary keys are encountered, all but the last instance are ignored.

So I don't think there's any way for a Structured Field parser to detect a duplicate "type"—the only option is to mangle the previous Problem header.

darrelmiller commented 1 year ago

Speaking as an individual, I have to say, there is a lot of elegance in the simplicity of this

HTTP/1.1 400 Client Error
Problem: "http://example.com/errors/enhance-your-calm"

and this feels very natural to me

Problem: "https://example.net/problems/almost-out"; title="you're almost out of credit”; credit_left=20

If the use of sf-item helps to detect duplicate problem fields, then that seems like a win to me.

darrelmiller commented 1 year ago

@mnot @sdatspun2 As document authors, you have expressed a preference for the dictionary format. There are obviously pros and cons to both options. Do you wish to discuss this further, or consider the issue closed?

mnot commented 1 year ago

It seems like there's non-trivial support for switching to an Item. I don't think this header is really deployed anywhere yet, so that shouldn't be an issue -- but I'd like to have some confirmation of that (i.e., has anyone else deployed this, or heard of deploying it?).

I'll work on a PR so we can compare the options.