Skip to content
Santekno.com | Tech Tutorials and Trends
EN
📖 0%
01 Aug 2025 · 6 min read ·Article 32 / 125
Go

32 Setting Up an ORM (gorm) in graphql-go

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

32 Setting Up an ORM (gorm) in graphql-go: An Integrated Guide for Backend Engineers

For backend engineers in the Go (Golang) ecosystem, building a robust API often requires integrating a database, an ORM, and a GraphQL schema. Two popular tools in the Go world, gorm as the ORM and graphql-go as the GraphQL server, are the go-to choice for many teams. This article takes an in-depth look at setting up gorm in a graphql-go project, complete with code examples, simulations, flow diagrams, and tips from seasoned engineers.


🛠 Preparation: Installing Dependencies

Before writing any code, make sure the following packages are installed:

sh
1go get github.com/jinzhu/gorm
2go get github.com/go-sql-driver/mysql
3go get github.com/graph-gophers/graphql-go
4go get github.com/graph-gophers/graphql-go/relay

We’ll be using MySQL in this example. Feel free to swap in another driver as needed (postgres, sqlite, etc.).


👩‍💻 Schema & Requirements for the Project

We’ll simulate a simple scenario:

Use Case: Managing a list of users.

  • Each user has: id, name, email.

Database Schema

sql
1CREATE TABLE users (
2  id INT AUTO_INCREMENT PRIMARY KEY,
3  name VARCHAR(100),
4  email VARCHAR(100) UNIQUE
5);

GraphQL Schema

graphql
 1type User {
 2  id: ID!
 3  name: String!
 4  email: String!
 5}
 6
 7type Query {
 8  users: [User!]!
 9  user(id: ID!): User
10}
11type Mutation {
12  createUser(name: String!, email: String!): User
13}

👨‍🔬 Integrating gorm into graphql-go, Step by Step

Let’s break it down!

1. The GORM Model for User

go
 1// models/user.go
 2package models
 3
 4import "github.com/jinzhu/gorm"
 5
 6type User struct {
 7    gorm.Model
 8    Name  string `gorm:"type:varchar(100)"`
 9    Email string `gorm:"type:varchar(100);unique"`
10}

2. Setting Up the Database & Auto Migrate

go
 1// db/db.go
 2package db
 3
 4import (
 5    "github.com/jinzhu/gorm"
 6    _ "github.com/go-sql-driver/mysql"
 7    "log"
 8    "user-gql/models"
 9)
10
11func InitDB() *gorm.DB {
12    db, err := gorm.Open("mysql", "root:password@/userdb?charset=utf8&parseTime=True")
13    if err != nil {
14        log.Fatal(err)
15    }
16    db.AutoMigrate(&models.User{})
17    return db
18}

3. The GraphQL Resolver

A resolver is the ‘bridge’ between a GraphQL query/mutation and your Go code (including the ORM).

go
 1// resolver/resolver.go
 2package resolver
 3
 4import (
 5    "context"
 6    "user-gql/models"
 7    "github.com/jinzhu/gorm"
 8)
 9
10type Resolver struct {
11    DB *gorm.DB
12}
13
14// For the users query
15func (r *Resolver) Users(ctx context.Context) ([]*UserResolver, error) {
16    var users []models.User
17    if err := r.DB.Find(&users).Error; err != nil {
18        return nil, err
19    }
20    resolvers := make([]*UserResolver, len(users))
21    for i, user := range users {
22        resolvers[i] = &UserResolver{user}
23    }
24    return resolvers, nil
25}
26
27// Single query by ID
28func (r *Resolver) User(ctx context.Context, args struct{ ID int32 }) (*UserResolver, error) {
29    var user models.User
30    if err := r.DB.First(&user, args.ID).Error; err != nil {
31        return nil, err
32    }
33    return &UserResolver{user}, nil
34}
35
36// Mutation
37func (r *Resolver) CreateUser(ctx context.Context, args struct{ Name string; Email string }) (*UserResolver, error) {
38    user := models.User{Name: args.Name, Email: args.Email}
39    if err := r.DB.Create(&user).Error; err != nil {
40        return nil, err
41    }
42    return &UserResolver{user}, nil
43}
44
45// Resolver for the User type
46type UserResolver struct {
47    models.User
48}
49
50func (u *UserResolver) ID() graphql.ID     { return graphql.ID(fmt.Sprint(u.User.ID)) }
51func (u *UserResolver) Name() string       { return u.User.Name }
52func (u *UserResolver) Email() string      { return u.User.Email }

4. The GraphQL Schema

Create a schema.graphql file with the following content:

graphql
 1type User {
 2  id: ID!
 3  name: String!
 4  email: String!
 5}
 6
 7type Query {
 8  users: [User!]!
 9  user(id: ID!): User
10}
11type Mutation {
12  createUser(name: String!, email: String!): User
13}

5. Integrating the HTTP Handler

go
 1// main.go
 2package main
 3
 4import (
 5    "io/ioutil"
 6    "net/http"
 7    "user-gql/db"
 8    "user-gql/resolver"
 9
10    "github.com/graph-gophers/graphql-go"
11    "github.com/graph-gophers/graphql-go/relay"
12)
13
14func main() {
15    // Setup DB
16    database := db.InitDB()
17    defer database.Close()
18
19    // Load schema
20    schemaBytes, err := ioutil.ReadFile("schema.graphql")
21    if err != nil {
22        panic(err)
23    }
24
25    // Build the GraphQL schema
26    schema := graphql.MustParseSchema(
27        string(schemaBytes),
28        &resolver.Resolver{DB: database},
29    )
30
31    http.Handle("/query", &relay.Handler{Schema: schema})
32
33    // Live!
34    http.ListenAndServe(":8080", nil)
35}

🏃 Simulating Queries Against the Server

1. Query All Users

graphql
1query {
2  users {
3    id
4    name
5    email
6  }
7}

Response:

json
1{
2  "data": {
3    "users": [
4      {"id": "1", "name": "Ridwan", "email": "ridwan@contoh.com"},
5      {"id": "2", "name": "Rahma", "email": "rahma@company.com"}
6    ]
7  }
8}

2. Mutation: Add a User

graphql
1mutation {
2  createUser(name: "Bimo", email: "bimo@team.com") {
3    id
4    name
5  }
6}

📊 Table: GORM vs Raw SQL Comparison

FeatureGORMRaw SQL
Query BuilderYES (ORM style)NO
Auto MigrationYESNO
RelationsYES (Preload, Joins)Manual (Join)
Struct MappingYES (Struct to Table)Handcrafted
Error HandlingMid (has an error type)Manual/built-in errors
ReadabilityCleaner & more idiomaticSometimes verbose

🔖 Setup Flow Diagram

MERMAID
flowchart TD
    A[Inisiasi: Load Schema GraphQL] --> B[Init GORM DB]
    B --> C[Bind Resolver ke GORM DB]
    C --> D[GraphQL HTTP Handler aktif]
    D --> E[Receive HTTP Request /query]
    E --> F{Jenis Query}
    F -- Query user/users --> G[GORM query ke DB]
    F -- Mutation --> H[GORM transaksi ke DB]
    G & H --> I[Json Response via GraphQL]

⚡️ Engineering Tips

  • Connection Pool: Use db.DB().SetMaxOpenConns(...) to optimize performance.
  • Env Config: Store database credentials in environment variables, not hardcoded.
  • Validation: Validate input in mutations before committing to the DB (don’t trust the client too much!).
  • Migration: Run migrations separately in production, not from the main app.
  • Testing: Use a test DB for integration tests, and mock GORM with a library such as go-sqlmock .

💬 Wrapping Up

With the setup above, you can connect the GORM ORM and graphql-go in a clean, tidy, and maintainable way. The key: always treat the resolver as a clean layer that connects the GraphQL world with your ORM/database.

Don’t hesitate to adapt this pattern to the needs of your own project, whether for e-commerce, SaaS, or enterprise scale. If you have any questions or need further explanation, drop them in the comments 😉


References:

Happy coding, backend warriors! 🚀

Related Articles

💬 Comments