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
Omit setting grpc fields to zero defaults #3119
Conversation
I was slightly surprised to learn the following code issues an error. Should I file a bug report, and/or attempt to address it? Field(14, "typed", Int64, func() {
Meta("struct:field:type", "time.Duration", "time")
Default(0 * time.Second)
})
Namely it appears that a default of |
While writing this I had several misgivings over the new-ish defaults behavior in gRPC at all. On the one hand, it means that setting a nonzero default makes it impossible to send a zero value over gRPC. On the other hand, without it a nonzero default silently does something you may not expect. I don't have a good resolution to offer here, but suspect we should err towards allowing it, and just clarify the documentation for dsl.Default(). If there's enough context to prove an unexpected interaction, perhaps issue a warning, or create a linter for this. I'm assuming any of that would be better off in a separate issue or PR. Let me know if you think it should be here. |
The PR looks good - thank you. Could you please rebase on the latest v3? As you probably know the challenge with gRPC is that the encoding doesn't support the notion of "missing" vs "has default value" since primitive values used in a gRPC message cannot be nil. We had a proposal to tackle this explicitly: #2221 - however this never got implemented. The proposal allows designers to define the desired behavior (i.e., allow or prevent a primitive field to have a zero value). |
ec21dea
to
ae87519
Compare
Rebased. Yes, the missing means zero, zero means default, etc. as covered on 2221 is why I was surprised to see missing mapped to defaults in v3. I must have missed the fanfare when it was introduced. :) Any thoughts on the inability to specify a default value of the type specified by Meta("struct:field:type")? Since the error seems to come from Default(), which presumably can't see a later Meta call, I expect at best a non-trivial fix. |
Wrt specifying default values for types equipped with Line 324 in 951acc0
|
I don't think IsCompatible has enough information. Maybe you can use - testing.go:18: [testdata/dsls.go:935] default value "" is incompatible with attribute of type int64 in attribute
+ testing.go:18: [../../dsl/attribute.go:236] default value _ is incompatible with attribute of type int64 in attribute The attempt did find one existing error worth fixing. I'm not satisfied with this approach yet so have kept it off the PR for now: f4b5a44 |
Yeah the type compatibility check for default values would have to be moved to the validation step of the DSL execution, probably here: https://github.com/goadesign/goa/blob/v3/expr/attribute.go#L189 (and it probably should have been there from the get go). Thank you again for this PR, merged! |
The expected behavior for zero-valued defaults bothered me; it needlessly compared the proto message fields against zeros only to set the goa fields to zeros. This PR explicitly tests a variety of built-in types and avoids the compare and set.
It's possible the isNonZero would be better written with reflect, to reduce its code. Or moved to, say, expr.AttributeType, so that we could instead write something like this in protobuf_transform: