-
Notifications
You must be signed in to change notification settings - Fork 213
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
Proposal: omitempty removal for relations #80
Comments
Hrm. I'm confused. You might say that the point of JSON api is to be able to transmit (in an efficient way) some part of an object graph to a client. How that is done, so long as it meets spec, should be up to the user of the library. I can see why someone would want to use both of these options. For example, if I specifically requested |
Relationships are part of a resource's fields. @genexp I'm not finding a specific recommendation, but my understanding is that a server typically returns all the fields of a resource unless a sparse fieldset has been requested. The @aren55555 I agree that |
The JSON API Spec does not say you can pick and choose which There should never be a case when a request for the same resource |
Proposal
This issue was filed as a proposal for the removal of the
omitempty
as an option in arelation
tag.Problem
To One
Say an application had the following structs, modeling a
Book
and theAuthor
that wrote it:Currently the application would be able to serialize the struct in two different ways:
1.
Book
had anAuthor
:2.
Book
without anAuthor
(anonymous):The client is to understand the first example as the
Book
in the payload was authored by Yann Martel. The second example is understood by the client as there was noAuthor
for thisBook
. When theomitempty
option is added to theBook
'sAuthor
field:The representation of a
Book
without anAuthor
is no longer possible. When the relation isnil
the relation will be omitted from the JSON Payload:With the
omitempty
tag present in the relation, the ability to represent an empty to-one relationships via anull
resource linkage has been lost.To Many
The same problem is present with to-many relations, lets say an application models
Team
s andPlayers
s:The application would be able to serialize a
Team
structs'Players
in two ways:1.
Team
hadPlayers
s:2.
Team
did not have anyPlayers
(ie expansion team):The client is to understand the first example as the
Team
in the payload had 2Player
s. The second example is understood by the client as there were noPlayer
s for thisTeam
. When theomitempty
option is added to theTeam
'sPlayers
field:The representation of a
Team
withoutPlayer
s is no longer possible. When the relation is empty ([]*Player{}
) the relation will be omitted from the JSON Payload:With the
omitempty
tag present in the relation, the ability to represent an empty to-many relationships via an empty array[ ]
resource linkage has been lost.Solution
From here down the code samples are relying on 1.8rc3; to install it do:
go get golang.org/x/build/version/go1.8rc3 && go1.8rc3 download
Starting in go1.8 struct tags will be ignored during type conversions (see golang/go#16085 for commentary). This means you can have something like:
Go 1.8rc3 output:
Why does this help? This helps easily convert between different permutations of structs:
To One
Define:
Think of both of these structs as JSON presenters.
Book
would be used when you want to send/receive a representation of a book without anAuthor
over the wire - irrespective of whether or not the book actually even has an author.BookAndAuthor
would be used when you want to send/receive a representation of a book with anAuthor
over the wire - again irrespective of whether or not that particular book had an author.Converting between these is as easy as:
Depending on your server's/client's intention on what you need to send/receive over the wire you would pick the appropriate struct to use. If you only ever need to send/receive a
Book
with anAuthor
you would only have theBookAndAuthor
struct (you would probably also rename it to justBook
at that point also). In the example aboveb2
would have been serialized.Conversely, if you only ever intend send/receive a
Book
without theAuthor
on the wire, you would only have theBook
struct. In the example above that means you would serializeb1
.To Many
Again each struct is used depending on the server's/client's intention. If you don't want
Players
on the wire useTeam
; if you do wantPlayers
on the wire useTeamAndPlayers
. Again the conversion between them is trivial.Summary
I think this solution makes more sense than the
omitempty
tag for these reasons:omitempty
tag obfuscates this complicationomitempty
was used in combination with go1.8, 2 structs would still be needed to cover all casesjsonapi
struct tags is more intuitive than looking through the documentation/source to discover theomitempty
functionality for arelation
The text was updated successfully, but these errors were encountered: