Replies: 5 comments 1 reply
-
the JSON tags don't work on the private field.
How about this? func GetSpecies(a Animal) string {
switch t := a.(type) {
case Dog:
return t.Species
case Human:
return t.Species
}
panic("Unknow type")
} |
Beta Was this translation helpful? Give feedback.
-
Woops, I missed one of the JSON tags, thanks. Your solution works fine for my example, but it starts getting cumbersome if you have 10+ things implementing the interface. It also doesn't work if you are writing a library that contains an interface other developers will implement themselves. |
Beta Was this translation helpful? Give feedback.
-
I implemented this in this PR #2218 I do not have a solution in place for a constructor, it only has getter/setter methods for the interface fields. |
Beta Was this translation helpful? Give feedback.
-
I wonder if a better solution would be to generate a normal struct from a GraphQL interface and embed that struct into generated structs. type Animal struct {
Species string `json:"species"`
}
type Human struct {
Animal
Name string `json:"name"`
}
type Dog struct {
Animal
Breed string `json:"breed"`
} Interfaces in Go are generally meant for defining behavior, not fields/data. Interfaces in GraphQL are the opposite and are more akin to the usage of embedded structs. This solution also avoids the issue of unexported fields. |
Beta Was this translation helpful? Give feedback.
-
Closed the previous PR in favor of this one #2220 that uses embedded structs instead of Go interfaces. |
Beta Was this translation helpful? Give feedback.
-
Current behavior
Today, when gqlgen processes the following schema:
It produces the following Go:
This approach isn't conducive to actually using the
Animal
interface in your own Go code. For example, I can't access the<Animal>.Species
field in a function that accepts an Animal as a parameter:Proposed behavior
The schema above could instead produce the following Go:
This allows access to the interface's fields via the method:
This would obviously be a breaking change that would need to be opted into via a config option.
One potential problem that needs some discussion is setter methods (since getters are already covered above), as well as constructors for setting unexported fields. Alternatively, the fields could remain exported, but we could simply add
GetSpecies()
(for example) methods for interface fields, so that the names wouldn't conflict (GetSpecies()
vsSpecies
).Beta Was this translation helpful? Give feedback.
All reactions