-
Notifications
You must be signed in to change notification settings - Fork 790
No empty object #965
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
No empty object #965
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| --- | ||
| id: 25001 | ||
| state: draft | ||
| created: TBD | ||
| placement: | ||
| category: gcp | ||
| --- | ||
|
|
||
| # Empty Objects | ||
|
|
||
| Fields of type Message **must not** be empty. Empty messages do not have uniform | ||
|
|
||
| ## Alternatives | ||
|
|
||
| The presence of empty Messages are sometimes used to indicate that a flag is enabled. Alternatives to empty Messages could include a single boolean field within the Message to signify enablement or an Enum rather than an empty Message. | ||
|
|
||
| ### Add Field to Message | ||
| For example: | ||
| ```proto | ||
| message EnableMyFeature { | ||
| } | ||
| ``` | ||
| Could be modeled instead as: | ||
|
|
||
| ```proto | ||
| message MyFeature { | ||
| bool enabled = 1; | ||
| } | ||
| ``` | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't remember seeing this as purely enablement, outside a oneof. Often it's "here's a message which might contain more information later" and its presence is indicative of the choice for that feature.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, it's usually an object that could contain more information later. I think that's where adding the One of the problems I'm trying to solve here is that there are many ways to implement behavior off of an empty message, none of which are clear to the user. To a user that is new to an API seeing an empty object documented in the REST docs is confusing, and it is unclear how or why to use such a field. Some of this confusion is contributed to by our generated documentation for empty objects like the following. DLP primitive transformations have a field replaceWithInfoTypeConfig that is an empty object. The generated documentation for this field seems broken to a viewer, but is technically correct. I don't think that the documentation generation is to blame here though. This pattern is nonstandard and nonintuitive to users, which is why generated tools and docs end up with a sub-par experience.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But
I agree that we can and should improve documentation - but I believe that's all that we should do here. I don't believe we should be artificially requiring an additional field. As a side-note, I'm going to do some research on:
That may provide some additional food for thought. |
||
| ### Move Option to Top-Level Enum | ||
|
|
||
| For a situation where the presence of an empty Message indicates a certain option is being chosen, an alternative is to choose the option via an enum rather than the presence of a particular object. | ||
|
|
||
| For example: | ||
| ```proto | ||
| oneof access_model { | ||
| AccessModelFree free = 1 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. would it make sense for this oneof to have unspecified? or some default value, as with any other enum value? IIRC that works around backwards compatibility issues where the returned enum is not a value that is present in older versions of a client. |
||
| AccessModelQuota quota = 2 | ||
| } | ||
|
|
||
| message AccessModelFree { | ||
| } | ||
|
|
||
| message AccessModelQuota { | ||
| int32 requests_per_day = 1; | ||
| } | ||
| ``` | ||
|
|
||
| Could be modeled instead as: | ||
| ```proto | ||
| enum AccessModel { | ||
| UNSPECIFIED = 0; | ||
| FREE = 1; | ||
| QUOTA = 1; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: |
||
| } | ||
|
|
||
| message AccessModelQuota { | ||
| int32 requests_per_day = 1; | ||
| } | ||
| ``` | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Except you've then got far more potential for conflicting options having their details specified at the same time. The oneof pattern is much more sensible IMO... if tools are unable to handle empty messages, I'd far prefer them to be improved.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tend to agree that the proposal of sidelined enum configuration over the values in the enum itself has poor usability: it requires the user to look at two different values (the enum and the corresponding configuration message) to reason about which value is correct. I can see the argument about an empty top-level message, but what's the issue with an empty enum value? it's clear what the type of the object is from the enum itself. |
||
|
|
||
|
|
||
| ## Changelog | ||
|
|
||
| - **TBD**: Created | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that this sentence is too broad in its guidance. Empty messages are very useful for future proofing APIs, whether it be a response message, Operation metadata, or just a nested message in a resource. I don't think the use of empty messages should be banned completely. It looks like you have a couple of specific scenarios, I think the guidance should focus on those scenarios, and potentially outline when it is OK to use empty messages (i.e. in the scenarios i've mentioned above).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, ok how about something like:
Messages within the body of resource requests or responses must not be empty.
No problems with empty responses as a concept, or empty operation information. Just empty objects within resources are the target