[
https://issues.apache.org/jira/browse/THRIFT-2429?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13967431#comment-13967431
]
Randy Abernethy commented on THRIFT-2429:
-----------------------------------------
Hi Ben,
I agree that required should be used with care and that thrift required and pb
required are the same semantic. What I think may be falling through the cracks
is that PB has two settings to determine whether something is serialized,
"optional" & "required" but Apache Thrift has three, "optional", *normal* and
"required". Normal is the basic tool for interface evolution. Optional extends
the evolution features with the ability to optimize away fields that need not
be serialized.
For example, consider the following IDL:
{code:title=x.thrift|borderStyle=solid}
struct Trade {
1: required string fish //required requiredness
2: double price //normal requiredness
3: optional i32 size //optional requiredness
}
{code}
Note that price is not "optional" and it is not "required", it is "normal" a
third independent case.
Now imagine a client passes a Trade to a server with only "fish" set because it
has this old IDL:
{code:title=y.thrift|borderStyle=solid}
struct Trade {
1: required string fish //required requiredness
}
{code}
This will _not_ cause an exception. Neither "normal" (price), nor "optional"
(size) need be present in the stream when read. Only the "required" field is
required by the reader. Thus you can delete the "normal" price field and have
compatibility.
Now go the other way, imagine a client that knows the first IDL sends a Trade
with all three fields to a server that knows the second IDL. The server will
ignore the fields it does not recognize (price & size). Thus "normal" fields
can be added without breaking compatibility. They are not "required", they are
not "optional", they are "normal". They work like regular struct properties,
without the need for set/unset and testing for presence on the server, which
makes them straight forward to use, but they support interface evolution.
So what is the distinction between normal and optional? The difference is that
while both "size" and "price" are allowed to be absent on the deserializing
size, only "size" can be omitted on the serializing side. In other words,
serializers that know about the (normal) "price" field will always serialize
it. On the other hand the (optional) "size" field can be sent or not sent at
the discretion of the client. The client can optimize away "size" when it is
not needed.
So:
* required - has no evolution capability (as Jens says, you can't remove or add
these)
* normal - provides interface evolution support (you can safely add and delete
these)
* optional - provides interface evolution support and adds the ability to
optimize away the field during serialization
If you want to build a normal struct that is sent to a server but make sure
that you can evolve the interface down the road, "normal" requiredness works
great. It clearly communicates your intent (send the whole thing) and lets you
use the struct naturally (without set/unset/isset/testing on the server, etc.).
If you want to create a struct with 50 fields of which only two or three are
set at a time, optional is the way to go. Optional does not buy you any
additional interface evolution features, it lets you selectively serialize the
fields required.
You make a great point, in that we do not have decent docs on this stuff. One
of the requirements for this ticket!
Best,
Randy
> Provide option to not write default values, rely on receiver default
> construction instead
> -----------------------------------------------------------------------------------------
>
> Key: THRIFT-2429
> URL: https://issues.apache.org/jira/browse/THRIFT-2429
> Project: Thrift
> Issue Type: Improvement
> Components: C++ - Compiler
> Affects Versions: 0.9.1
> Reporter: Chris Stylianou
> Assignee: Randy Abernethy
> Labels: default, optional, required
>
> Would there be any objections to a patch that does not write default values
> (essentially the same logic as the optional attributes). This obviously
> relies on the receiving application using the same IDL version to ensure the
> defaults used on object construction match the senders.
--
This message was sent by Atlassian JIRA
(v6.2#6252)