A GraphQL oddity
Warning: I have tried to make this post not sound like a rant, but I think I failed.
Gqlgen is a golang gql library that is schema-first. That is to say, it is
somewhat declarative. It sounds like a good idea, but having used graphene and
very happy with it, I'm not quite sold on the "benefits" of being schema-first -
maybe it's something specific to Golang. I say "somewhat" because it takes care
of generating some boilerplate using go run github.com/99designs/gqlgen
generate
and then leaves you to write the actual resolvers.
If you annotate your code with a comment like this:
//go:generate go run github.com/99designs/gqlgen generate
You could just run go generate
. What's the point of that? I guess so that you
invoke all your code-generating code with one command. Could you just put them
all in Makefile
? Well, yes?
If you are familiar with macros in Lisp, you must be severely disappointed by this development. It suddenly feels like you've been transported to the city of Arkanar in Hard to be a God(2013). The backwardness is…grotesque.
Well, now that it's schema-first, it means that I can't use the language's
type-system to model my GraphQl schema. Say I wanted my GraphQL schema to look
something like this:
Python:
class DateFields: created_on = Column(DateTime) updated_on = Column(DateTime) class Bar(DateFields): count = Column(Float) class Foo(DateFields): name = Column(String) id = Column(UUIDType) barid = Column(UUIDType)
Golang:
type DateFields struct{ createdOn time.Time updateOn time.Time } type Bar struct{ DateFields count int } type Foo struct{ DateFields name string barID string }
This is the closest you can get to that in GraphQL:
type DateFields { createdOn: Time! updatedOn: Time! } type Bar { dateFields: DateFields! count: Int! } type Foo{ dateFields: DateFields! name: String! barID: ID! }
That's not quite the same thing, is it? My intention is to have shared fields, which I can achieve through inheritance in Python or embedding in Golang.
I'm sorry Dave, I can't let you do that.
In GraphQL, the only option is to resort to copy-pasting, string interpolation or implementation-specific features like custom directives. It's just odd, why is there no way to share fields in the GraphQL type system?