UP | HOME

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?

Date: 2022-04-12

Author: Brian Kamotho