OpenAPI-Specification
OpenAPI-Specification copied to clipboard
Behavior of `allowEmptyValue: false`
TL;DR: I have no idea how to define compliance criteria for allowEmptyValue: false, which is the default behavior, with setting true being NOT RECOMMENDED.
<rant>
The clarification added in 3.0.2 just says using it is NOT RECOMMENDED, which would, AFAICT, leave the default false behavior in place. Looking at the issue regarding that clarification, there is a lot there that never made it into the spec. Some of that says that setting it to true allows the undefined value behavior already defined by RFC6570.
However, style, explode, and allowReseved already control the RFC6570 behavior. Are we by default forbidding empty values? Does that mean RFC6570's undefined values (which includes null, empty arrays, empty objects, and objects where all properties are null, but NOT the empty string)? Does it impact the empty string as well? If schema allows these does the default allowEmptyValue: false behavior contradict that? How are implementations expected to support this?
If using content, does allowEmptyValue have meaning? What if the content is legitimately a zero-length string?
This seems like a field with a default value that blocks common cases in a very non-obvious way, requiring complex code to work around the normal behavior of Schema Objects, Media Type Objects, and RFC6570. Do we really expect implementations to enforce this? If we are recommending against its use, how do we expect users to support empty values, which can easily happen by accident (particularly empty arrays)? </rant>
We discussed in TSC and decided that since the use isn't recommended, we might try to continue as if this field does not exist.
After thinking on this more, the only interpretation I can come up with that makes sense to me is:
allowEmptyValue: truewas intended to allow empty values regardless of whether the schema allows them or not.- this would make
allowEmptyValue: false(the default) be a no-op: if the schema allows an empty value, then it is still allowed
It just doesn't make sense to me that the default would contradict how schemas work everywhere else. So it must be that the non-default value is the one that contradicts the schema. This would also parallel how nullable works by contradicting the established type.
In the absence of anyone knowing how this was supposed to work, that's what I'm going to explain in the text.
I think that allowEmptyValue is a hint for Swagger UI and similar tools on whether to allow users sending query options with an empty value instead of not sending the query option at all:
Visualization & try-out tools REALLY SHOULD render such a check box if (and only if) the parameter's schema accepts the empty string.
And the OAS editors REALLY SHOULD remove this thingy in future versions of the specification 😄
@ralfhandl The UI hint makes a little more sense, but would require different wording to clarify that intent.
But I'm not convinced of this interpretation either. What difference does it make to an API whether bar= (with an empty string value) is sent because of a web form or because of a programmatically constructed URL query string? Why would bar be omitted?
Is this about HTML's notion of what controls are successful, which defers whether to send an input that "lacks a value" or not to the implementation? (referencing HTML 4.0.1 because I can't be bothered to decipher WHATWG's pseudocode).
And again, how does that impact APIs? Are APIs expected to mimic web forms, in which case there's no difference, or is this a web-form-only thing, in which case why is it in the spec at all when many other web-form-related things are not?
If this is a UI hint, then I'll need to update the PR to say so.
What difference does it make to an API whether
bar=(with an empty string value) is sent
The question is how many different meanings an API sees in these three requests:
GET /foo
GET /foo?bar
GET /foo?bar=
Do absence (1) and presence (2, 3) of bar mean different things?
Do presence of bar without a value (2) and with a zero-length value (3) mean different things?
If an API author intends to have three different meanings, how do they express their intent in OpenAPI?
With required:false the author can express that form (1) is acceptable.
Then things get murky.
allowEmptyValue | boolean | Sets the ability to pass empty-valued parameters. This is valid only for either query or formData parameters and allows you to send a parameter with a name only(2) or an empty value(3). Default value is false.
So authors could express that forms (2) and (3) are allowed, but it was unclear how to distinguish (2) and (3).
Explicit mentioning of form (2) was taken away in OpenAPI 3.0.0, see here for the TSC's rationale.
Which leaves me puzzled why the keyword remained, instead of removing it and relying on style or content for allowing form (3).
My take:
- Don't try to fix
allowEmptyValuein 3.x, it is broken beyond repair. - Remove it in 4.0.
My take:
Don't try to fix allowEmptyValue in 3.x, it is broken beyond repair. Remove it in 4.0.
I agree
@ralfhandl no one's trying to "fix" this right now, I'm just trying to document what it does.
We're definitely all puzzled, and it was already agreed that it should be removed. But it is still here for now, and as written it appears to require contradicting schema and content. So is that what it does? Or is that not what it does? And if not, what does it do? Not "what should it do?", not "what do we want it to do", but "what is it doing right now that we don't understand?"
what it does
I'm afraid it does different things with/to different tools, and I definitely am unable to decide which of these is "right".
I assume we'll keep this open until we've forward-ported to 3.1.x and 3.2.x
I assume we'll keep this open until we've forward-ported to 3.1.x and 3.2.x
@lornajane yes that's how I've been tracking/closing issues with PRs for multiple branches.
PRs merged, closing!