Every so often, on Sundays (obviously), Commit engineering partners share an open source software tool they use to make their work and life easier. This week’s feature on gqlgen is by Bill Monkman, a Commit software developer with over 20 years of experience in backend development, DevOps, distributed systems and system architecture.
What is gqlgen?
gqlgen is a Go library used to build GraphQL servers. It takes a schema-first, code-generation-heavy approach, which eliminates a lot of boilerplate. GraphQL is a query language for APIs. It provides a fully typed, complete and understandable description of the data in your API, giving clients the power to ask for exactly what they need and nothing more. That makes it easier to evolve APIs over time and enables powerful developer tools.
Who is it good for?
People interested in GraphQL who want to write less REST and less custom documentation. Because GraphQL exposes its schema to users of your API, including any comments you’ve attached, it effectively describes the available operations and properties, as opposed to REST, where all the documentation has to be provided separately and often becomes out of sync with reality. People who are writing code in Go will likely appreciate the schema-first, code-generation approach taken by gqlgen.
What companies or products are using it?
Based on a thread in their GitHub repository, notable users include Bench Accounting, DigitalOcean, Khan Academy and Kyma.
Is there a story behind who created it and why they created it?
How did you find this tool, and why did you choose it over others?
I evaluated a bunch of Go libraries while I was at Bench Accounting and really liked the approach of gqlgen. I’m a fan of code generation, and the idea of being able to specify my schema based on the existing design of my system and generate almost everything was appealing. We’ve used it in a few different Commit projects now.
How does it work?
The workflow with gqlgen is typically to create a YAML file that tells it where to find your schema files, where to put generated code, and any mappings of objects in your schema to existing structs in your Go code.
This can be very handy, because if you have existing models you’re using for data access, or return values from some other internal API, you can reference them here, and you’ll be able to return these structs directly from your resolvers. Any models not mapped to existing structs will be generated for you by gqlgen.
Next, create your GraphQL schema to expose the data you want to be available to users of your API.
Then run the following to generate code based on your schema:
go run github.com/99designs/gqlgen
At this point it will have created stub resolvers for you to fill in.
In GQL terminology, a resolver is a function that contains the logic required to fill in part of your graph. Basically, since you have provided the schema that describes all the types of data available and the relationships, the resolvers are what actually fill in the right data for those types based on a given query.
Here’s an example resolver:
Notice that since we mapped a model to an existing struct, we were able to immediately return the struct we got back from the database. In other cases, you may want to do some transformation or change the type of return data. You can do that in the resolver. If the struct you provided doesn’t match the definition in the schema precisely, additional resolvers will be created for you to be able to massage the data into the correct format. Or, you could have gqlgen generate a model for you, and in your resolver you can create an instance of that and fill it in from whatever data sources you like.
It’s extremely easy to get started. Just go into an empty directory and run:
go mod init github.com/<your_name>/gql go run github.com/99designs/gqlgen init go run ./server/server.go
And you’ll have a local gql playground to explore. It will generate the files I mentioned earlier (gqlgen.yml, graphql.schema and resolver.go), which you can easily edit to see how it feels to fill in resolvers.
gqlgen takes the convenience and flexibility that GraphQL provides developers a step further by:
- Guiding people towards more thoughtful system design through a schema-first approach
- Reducing the overhead of implementing such a system by generating most of the boilerplate for you
- Ensuring integrity by enforcing type-safety
If you’re interested in Go or GraphQL, check it out.
Stay tuned for future Open Source Sundays, and have a look through the Commit blog for more interesting content.
Thank you to Bill Monkman for writing this article.