102 Setting Up Your First gqlgen Project
102 Setting Up Your First gqlgen Project
Building an effective GraphQL application from scratch has become increasingly easier thanks to the many tools available in the Go ecosystem. One that is quite popular and powerful is gqlgen . This library offers a practical, performant, and idiomatic way to build GraphQL APIs in Golang. In this article, I’ll guide you—in the style of a hands-on engineer—through setting up your first gqlgen project, from initialization all the way to running a simple query.
Why gqlgen?
Without going on too long, here are some of the main reasons I chose gqlgen:
- Type-safe. The GraphQL schema is generated as static Go code.
- Performance. Zero reflection, so execution is faster.
- Extendable. It can be tailored to fit your business needs.
Prerequisites
Make sure you already have installed:
- Go 1.18+
- Git (for versioning and cloning the library repo)
- Node.js and npm only if you want the GUI playground, optional
Step 1: Bootstrapping the Project
Let’s start at the most basic level. Create a project folder and initialize a Go module.
1$ mkdir gqlgen-demo
2$ cd gqlgen-demo
3$ go mod init github.com/username/gqlgen-demoThen, install gqlgen:
1$ go get github.com/99designs/gqlgenStep 2: Create the GraphQL Schema
As is best practice in GraphQL, we start by defining the schema (.graphqls). Create a graph folder and a schema file:
1$ mkdir graph
2$ touch graph/schema.graphqlsA simple schema example:
1# graph/schema.graphqls
2type Query {
3 hello: String!
4 todos: [Todo!]!
5}
6
7type Todo {
8 id: ID!
9 text: String!
10 done: Boolean!
11}Step 3: Generate the gqlgen Boilerplate
So that we don’t have to write struct and resolver code manually, we use gqlgen’s codegen.
1$ go run github.com/99designs/gqlgen generateThe command above generates several files automatically (:rocket:), for example:
graph/model/models_gen.go: structs based on the schemagraph/schema.resolvers.go: resolver stubs, the area for our business logicgqlgen.yml: the generator config
Directory structure:
1gqlgen-demo/
2 ├── go.mod
3 ├── gqlgen.yml
4 └── graph/
5 ├── model/
6 │ └── models_gen.go
7 ├── schema.graphqls
8 └── schema.resolvers.goStep 4: Implement the Resolver
Let’s fill in the logic for the resolvers that were just generated. Two resolvers: Query.hello and Query.todos.
1// graph/schema.resolvers.go
2package graph
3
4import (
5 "context"
6 "github.com/username/gqlgen-demo/graph/model"
7)
8
9var todos = []*model.Todo{
10 {ID: "1", Text: "Learn gqlgen", Done: false},
11 {ID: "2", Text: "Implement GraphQL", Done: true},
12}
13
14func (r *queryResolver) Hello(ctx context.Context) (string, error) {
15 return "Hello developer!", nil
16}
17
18func (r *queryResolver) Todos(ctx context.Context) ([]*model.Todo, error) {
19 return todos, nil
20}If you look closely, the struct types and resolver functions are already auto-generated. After that, the actual logic is easy to fill in according to your specifications.
Step 5: Set Up the Entry Point (main.go)
We need an HTTP server to expose the GraphQL API. Use net/http and the graph.NewExecutableSchema handler.
1package main
2
3import (
4 "log"
5 "net/http"
6 "github.com/99designs/gqlgen/graphql/handler"
7 "github.com/99designs/gqlgen/graphql/playground"
8 "github.com/username/gqlgen-demo/graph"
9 "github.com/username/gqlgen-demo/graph/generated"
10)
11
12func main() {
13 srv := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}}))
14
15 http.Handle("/", playground.Handler("GraphQL playground", "/query"))
16 http.Handle("/query", srv)
17
18 log.Println("connect to http://localhost:8080/ for GraphQL playground")
19 log.Fatal(http.ListenAndServe(":8080", nil))
20}Step 6: Run & Test the Query
Run the server:
1$ go run .Open http://localhost:8080 in your browser. You’ll see the playground’s GUI query interface. Now run the following query:
1query {
2 hello
3 todos {
4 id
5 text
6 done
7 }
8}The result should look like this:
1{
2 "data": {
3 "hello": "Hello developer!",
4 "todos": [
5 {
6 "id": "1",
7 "text": "Learn gqlgen",
8 "done": false
9 },
10 {
11 "id": "2",
12 "text": "Implement GraphQL",
13 "done": true
14 }
15 ]
16 }
17}GraphQL Request Flow Diagram (Mermaid)
Let’s visualize how a request is processed from the client to the resolver:
sequenceDiagram
participant Client
participant Server
participant Resolver
Client->>Server: Send GraphQL Query
Server->>Resolver: Delegate to resolver (e.g., Query.todos)
Resolver-->>Server: Return the data result
Server-->>Client: Send JSON response
Table: Comparison of gqlgen vs Other GraphQL Libraries in Go
| Feature | gqlgen | graphql-go | thunder-graphql |
|---|---|---|---|
| Type-safety | ✅ | ❌ | ✅ |
| Performance | ⭐️⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ |
| Schema first | ✅ | ✅ | ❌ |
| Subscriptions Support | ✅ | Limited | Limited |
| Plug & Play model-gen | ✅ | ❌ | ❌ |
| Documentation | Excellent | Okay | Sparse |
Troubleshooting & Best Practices
Schema changes
After changingschema.graphqls, don’t forget to regenerate:1$ go run github.com/99designs/gqlgen generateProtobuf/Custom Model
You can map a custom model (for example, from Protobuf/Ent).Scaffolding
For a new project, you can also use the init CLI:1$ go run github.com/99designs/gqlgen init
Conclusion
By following the simple steps above, you have successfully set up your first gqlgen project, ready to serve as the foundation for a production-grade GraphQL system in Go.
Once you understand the basics, you can explore advanced features such as middleware, pagination, subscriptions, database integration, and resolver testing.
What has your experience with gqlgen been like? If you run into any issues or have insights, feel free to share them in the comments. Good luck, and happy hacking! 🚀
References: