-
Notifications
You must be signed in to change notification settings - Fork 171
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
Go SDK: NullableString awkwardness #1198
Comments
How is this issue progressing? It is in working stage or still in proposal? And I am playing around find this solution can also pass the compiler (but we need to change version in type Nullable[T any] struct {
V T
Valid bool
}
type NullableString Nullable[*string]
func NewNullableString(s *string) NullableString {
if s == nil {
return NullableString{V: s, Valid: false}
}
return NullableString{V: s, Valid: true}
} |
Sorry, we didn't really get to it yet, but @svix-jplatte added a label a couple of weeks ago to make sure we don't miss it and fix it soon! |
I think @svix-onelson is working on upgrading the OpenAPI generator which will also fix this. |
@svix-onelson, is this fixed? |
This doesn't look so different with the latest generator. I think what I'd like to do for this is to expose/re-export I'd like to avoid adding a new type (though generics will now be on the table since we're targeting go 1.20) as described in #1198 (comment). The rationale being I think we'd need to template around set/unset checks in the rest of the codegen output to account for the new type. |
Fixes <#1198> While this isn't quite the type of change that was requested in #1198, I'm hopeful it'll reduce a bit of the friction. A new constructor is now available as `svix.StaticNullableString()` which gives an `openapi.NullableString`. Note that the return type (not a pointer) is inconsistent with the rest of the functions that act as primative constructors, and in fact goes against the convention of constructors returning pointers to the value they initialize. The issue was raised, however, that all the places in the lib where a `NullableString` is needed, we'd have to dereference it anyway. Since this alt constructor is all about convenience, we may as well break convention. _In for a penny, in for a pound..._ The net effect is instead of: ```go appIn := svix.ApplicationIn{ ... Uid: *svix.NullableString(svix.String("myuid")) } ``` folks will now be able to write: ```go appIn := svix.ApplicationIn{ ... Uid: svix.StaticNullableString("myuid") } ```
) Fixes <#1198> While this isn't quite the type of change that was requested in #1198, I'm hopeful it'll reduce a bit of the friction. A new constructor is now available as `svix.StaticNullableString()` which gives an `openapi.NullableString`. Note that the return type (not a pointer) is inconsistent with the rest of the functions that act as primative constructors, and in fact goes against the convention of constructors returning pointers to the value they initialize. The issue was raised, however, that all the places in the lib where a `NullableString` is needed, we'd have to dereference it anyway. Since this alt constructor is all about convenience, we may as well break convention. _In for a penny, in for a pound..._ The net effect is instead of: ```go appIn := svix.ApplicationIn{ ... Uid: *svix.NullableString(svix.String("myuid")) } ``` folks will now be able to write: ```go appIn := svix.ApplicationIn{ ... Uid: svix.StaticNullableString("myuid") } ```
The way that the Go SDK handles optional strings is somewhat awkward, and while this ship may have sailed, @tasn asked me to provide some feedback here.
First of all, I totally understand that there's a need for a
NullableString
type of some kind. While idiomatic Go loves to use "zero values" including the empty string, other languages and APIs don't always work well with that, and so a string type that can also represent unset/JSONnull
is necessary.But the implementation and use of
NullableString
in the Go SDK is awkward. Perhaps the most awkward aspect is that the helper functionsvix.NullableString
a) takes a*string
rather than astring
, and b) returns not anopenapi.NullableString
but a*openapi.NullableString
.That means that the only way to create an
openapi.NullableString
from a static string literal in a single line, is the rather unwieldy*svix.NullableString(svix.String("mystring"))
.The problem is compounded by the fact that
openapi.NullableString
is a private type, and as a result it is impossible to write 3rd-party code that manipulates it directly:What's particularly odd about the choice to return a pointer from
svix.NullableString
is that the data types that need nullable strings only ever want anopenapi.NullableString
, not a pointer to one, which leads to code like:Suggested alternative
I think a much more Go-friendly implementation here would be to make the type something like
database/sql
'sNullString
(https://pkg.go.dev/database/sql#NullString).and then define your helper function as
That creates a situation where the zero-valued
types.NullableString
is null, because the zero value ofValid
isfalse
:And constructing one to pass into a type is equally straightforward:
Here's another example to play around with: https://go.dev/play/p/jYGq7qCCC11
The text was updated successfully, but these errors were encountered: