6 Initializing a Go Project for GraphQL
6 Initializing a Go Project for GraphQL
GraphQL is increasingly being adopted as a modern API solution thanks to its flexibility and efficiency in fetching data. Go (Golang), with its impressive performance and mature tooling ecosystem, has become one of the favorite languages for building production-grade GraphQL servers.
However, like many new stacks, starting a GraphQL project with Go can feel like overkill if you aren’t familiar with the tooling ecosystem, directory structure conventions, or the right dependency management techniques. This article breaks down 6 steps to initialize a Go project for GraphQL—from setting up the project to having an API ready to test.
1. Project Scaffolding and Dependency Management
The first step is to create a clean directory structure and initialize dependency management.
Basic Directory Structure
1my-graphql-app/
2├── cmd/
3│ └── server/
4│ └── main.go
5├── internal/
6│ ├── graphql/
7│ └── model/
8├── go.mod
9└── go.sumInitializing the Project with Go Modules
1go mod init github.com/username/my-graphql-appAdding the Minimum Dependencies
The most popular library for GraphQL in Go is 99designs/gqlgen
:
1go get github.com/99designs/gqlgenGqlgen provides a schema generator and makes creating both resolvers and models much easier.
Table: Comparison of GraphQL Libraries in Go
| Library | Strengths | Weaknesses |
|---|---|---|
| gqlgen | Automated schema & typegen | Requires extra configuration |
| graphql-go | Lightweight, simple API | Lacks advanced features |
| thunder-graphql | Database integration | Small community |
2. Define the GraphQL Schema (schema.graphqls)
GraphQL is “schema-first,” so start by defining the schema:
Example schema.graphqls
1type User {
2 id: ID!
3 name: String!
4 email: String!
5}
6
7type Query {
8 users: [User!]!
9 user(id: ID!): User
10}File Structure:
1internal/graphql/
2└── schema.graphqlsIn real-world designs, the schema should be modular so it’s easy to scale: for example user.graphqls, product.graphqls, and so on.
3. Generate Models & Resolvers with Gqlgen
Once the schema is ready, run the gqlgen generator, which will create the basic Go blueprint files:
1go run github.com/99designs/gqlgen generateThe result:
1internal/graphql/
2├── generated.go
3├── models_gen.go
4├── resolver.go
5└── schema.resolvers.gogenerated.go: auto-generated code representing all GraphQL operations.models_gen.go: Go structs compiled from the definitions in the schema.resolver.goandschema.resolvers.go: where the business logic is implemented.
4. Implementing the Resolver
The resolver is the “heart” of a GraphQL server—the place where every query, mutation, and subscription is executed.
Example Query Resolver Implementation
1// internal/graphql/resolver.go
2package graphql
3
4type Resolver struct {
5 users []*model.User
6}
7
8// internal/graphql/schema.resolvers.go
9func (r *queryResolver) Users(ctx context.Context) ([]*model.User, error) {
10 return r.Resolver.users, nil
11}
12
13func (r *queryResolver) User(ctx context.Context, id string) (*model.User, error) {
14 for _, user := range r.Resolver.users {
15 if user.ID == id {
16 return user, nil
17 }
18 }
19 return nil, nil
20}Simulating a Request Response
Query:
1{ 2 users { 3 id 4 name 5 email 6 } 7}Response:
1{ 2 "data": { 3 "users": [ 4 {"id": "1", "name": "Andi", "email": "andi@domain.com"}, 5 {"id": "2", "name": "Budi", "email": "budi@domain.com"} 6 ] 7 } 8}
5. Setting Up the Server and Routing
To make the server accessible, set up an HTTP handler. Typically, a popular mux such as net/http or chi
is used.
Minimal Server Example
1// cmd/server/main.go
2package main
3
4import (
5 "log"
6 "net/http"
7 "github.com/99designs/gqlgen/graphql/handler"
8 "github.com/99designs/gqlgen/graphql/playground"
9 "github.com/username/my-graphql-app/internal/graphql"
10)
11
12func main() {
13 srv := handler.NewDefaultServer(graphql.NewExecutableSchema(graphql.Config{Resolvers: &graphql.Resolver{}}))
14
15 http.Handle("/graphql", srv)
16 http.Handle("/", playground.Handler("GraphQL playground", "/graphql"))
17
18 log.Println("Server started at http://localhost:8080/")
19 log.Fatal(http.ListenAndServe(":8080", nil))
20}The GraphQL Playground can be accessed at http://localhost:8080/.
6. Preparing the Configuration and Environment
Separating configuration makes the system more scalable and easier to deploy across different environments (dev, staging, prod).
Standard: Use .env for environment variables
Install a loader package such as godotenv :
1go get github.com/joho/godotenvUsage Example
1import "github.com/joho/godotenv"
2
3func init() {
4 godotenv.Load() // will read the .env file at the project root
5}.env Example
1PORT=8080
2DATABASE_URL=postgres://user:pass@localhost:5432/dbnameThe GraphQL Go Project Initialization Flow
Let’s visualize it with a mermaid diagram:
flowchart TD
A[Mulai] --> B[Inisialisasi Go Modules]
B --> C[Buat struktur direktori]
C --> D[Definisikan schema GraphQL]
D --> E[Generate code dengan gqlgen]
E --> F[Implementasi resolver]
F --> G[Setup server HTTP]
G --> H[Konfigurasi environment]
H --> I[Selesai]
Conclusion
Initializing a Go project for GraphQL is very straightforward when you follow these 6 steps:
- Scaffolding & Dependencies: Set up the folder structure and install dependencies.
- Schema: Design the initial schema based on the application’s needs.
- Auto-Generate Models & Resolvers: Use gqlgen to generate the boilerplate code.
- Resolver Implementation: Code the query/mutation logic as needed.
- Server: Set up the router and HTTP server so GraphQL is exposed.
- Configuration: Manage environment configuration via environment variables.
With Go’s efficient runtime, a type-safe static schema, easy deployment, and mature tooling, this stack is one of the go-to choices for modern GraphQL-based backends.
Ready to try this stack in your next project?
Additional References
If you have any questions or other experiences regarding initializing a GraphQL project with Go, feel free to share them in the comments!