Skip to content
Santekno.com | Level Up Your Engineering Skills
ID
📖 0%
29 Oct 2025 · 5 mnt baca ·Artikel 121 / 125
Go

121 Studi Kasus: API GraphQL Produk & Kategori dengan gqlgen

IH
Ihsan Arif
Penulis di Santekno · Backend Engineer

title: 121 Studi Kasus: API GraphQL Produk & Kategori dengan gqlgen
subtitle: Membongkar Arsitektur, Implementasi, dan Studi Kasus API Product-Categories dengan gqlgen di Golang
author: insinyursoftware
date: 2024-06-22
tags: [graphql, golang, gqlgen, backend, studi-kasus, api]

GraphQL semakin populer sebagai solusi API yang fleksibel, terutama untuk skenario relasi data yang kompleks. Di antara sekian banyak tools di ekosistem Go, gqlgen muncul sebagai salah satu framework paling solid untuk membangun GraphQL API di Golang.

Dalam artikel ini, saya akan membagikan pengalaman membangun API sederhana untuk produk dan kategori, lengkap dengan studi kasus, simulasi query, dan pembahasan arsitektur kode menggunakan gqlgen. Untuk pemahaman lebih baik, saya sertai contoh kode, skema database sederhana, dan visualisasi flow pengambilan data antar entitas.


1. Studi Kasus

Anggap saja kita membangun sebuah sistem e-commerce sederhana yang hanya memiliki dua entitas utama:

  1. Produk
    • Memiliki id, nama, harga, dan kategori_id.
  2. Kategori
    • Memiliki id dan nama.

Hubungan antar entitas:

  • Produk dimiliki oleh satu Kategori.
  • Kategori bisa memiliki banyak Produk.

Kita ingin menyediakan API yang mampu:

  • Query daftar produk beserta detail kategorinya.
  • Query daftar kategori beserta produk-produknya.
  • Mendukung filter dan relasi.

2. Struktur Database

Berikut ini tabel relasional yang digunakan:

produkkategori
id (int)id (int)
nama (string)nama (string)
harga (int)
kategori_id

3. Merancang Schema GraphQL

Kita mulai dari mendefinisikan schema GraphQL (schema.graphqls):

graphql
 1type Produk {
 2  id: ID!
 3  nama: String!
 4  harga: Int!
 5  kategori: Kategori!   # ini relasi Kategori (One-to-Many)
 6}
 7
 8type Kategori {
 9  id: ID!
10  nama: String!
11  produk: [Produk!]!   # ini relasi Produk (Many-to-One)
12}
13
14type Query {
15  produkList: [Produk!]!
16  kategoriList: [Kategori!]!
17  produkByKategori(kategoriId: ID!): [Produk!]!
18}

4. Struktur Proyek

Pastikan struktur project kurang lebih seperti ini:

text
 1.
 2├── gqlgen.yml
 3├── go.mod
 4├── main.go
 5├── graph
 6│   ├── model
 7│   │   └── models_gen.go
 8│   ├── resolver.go
 9│   ├── schema.graphqls
10│   ├── schema.resolvers.go
11│   └── database.go

5. Implementasi dengan gqlgen

a. Generate Code Skeleton

Install dulu:

sh
1go get github.com/99designs/gqlgen
2go run github.com/99designs/gqlgen generate

Setelah itu, gqlgen akan mengenerate boilerplate untuk resolver dan model.


b. Membuat Mock Database

Untuk studi kasus, kita cukup in-memory data store sederhana saja.

go
 1// graph/database.go
 2
 3package graph
 4
 5import "graph/model"
 6
 7var kategoriData = []*model.Kategori{
 8    {ID: "1", Nama: "Elektronik"},
 9    {ID: "2", Nama: "Fashion"},
10}
11
12var produkData = []*model.Produk{
13    {ID: "1", Nama: "Laptop", Harga: 10000000, KategoriID: "1"},
14    {ID: "2", Nama: "HP", Harga: 4000000, KategoriID: "1"},
15    {ID: "3", Nama: "Celana Jeans", Harga: 250000, KategoriID: "2"},
16}

Tambahkan field KategoriID ke model. Jika auto-generation belum mendukung, edit langsung modelnya:

go
1// graph/model/models_gen.go
2type Produk struct {
3    ID         string     `json:"id"`
4    Nama       string     `json:"nama"`
5    Harga      int        `json:"harga"`
6    KategoriID string     `json:"kategoriId"` // penting untuk relasi!
7    Kategori   *Kategori  `json:"kategori"`
8}

c. Implementasi Resolver

Query produkList

go
 1// graph/schema.resolvers.go
 2
 3func (r *queryResolver) ProdukList(ctx context.Context) ([]*model.Produk, error) {
 4    return produkData, nil
 5}
 6
 7func (r *queryResolver) KategoriList(ctx context.Context) ([]*model.Kategori, error) {
 8    return kategoriData, nil
 9}
10
11func (r *queryResolver) ProdukByKategori(ctx context.Context, kategoriID string) ([]*model.Produk, error) {
12    var result []*model.Produk
13    for _, p := range produkData {
14        if p.KategoriID == kategoriID {
15            result = append(result, p)
16        }
17    }
18    return result, nil
19}

Resolver Field Relasi

Karena di schema Produk punya field kategori, kita perlu resolver custom untuk ini:

go
1func (r *produkResolver) Kategori(ctx context.Context, obj *model.Produk) (*model.Kategori, error) {
2    for _, k := range kategoriData {
3        if k.ID == obj.KategoriID {
4            return k, nil
5        }
6    }
7    return nil, errors.New("kategori not found")
8}

Dan pada Kategori ada field produk (many-to-one):

go
1func (r *kategoriResolver) Produk(ctx context.Context, obj *model.Kategori) ([]*model.Produk, error) {
2    var result []*model.Produk
3    for _, p := range produkData {
4        if p.KategoriID == obj.ID {
5            result = append(result, p)
6        }
7    }
8    return result, nil
9}

6. Simulasi Query

Query Produk beserta Kategori

graphql
 1query {
 2  produkList {
 3    id
 4    nama
 5    harga
 6    kategori {
 7      id
 8      nama
 9    }
10  }
11}

Response:

json
 1{
 2  "data": {
 3    "produkList": [
 4      {
 5        "id": "1",
 6        "nama": "Laptop",
 7        "harga": 10000000,
 8        "kategori": {
 9          "id": "1",
10          "nama": "Elektronik"
11        }
12      },
13      ...
14    ]
15  }
16}

Query Kategori dan Daftar Produk-nya

graphql
 1query {
 2  kategoriList {
 3    id
 4    nama
 5    produk {
 6      id
 7      nama
 8      harga
 9    }
10  }
11}

Response:

json
 1{
 2  "data": {
 3    "kategoriList": [
 4      {
 5        "id": "1",
 6        "nama": "Elektronik",
 7        "produk": [
 8          { "id": "1", "nama": "Laptop", "harga": 10000000 },
 9          { "id": "2", "nama": "HP", "harga": 4000000 }
10        ]
11      },
12      // dst
13    ]
14  }
15}

7. Diagram Alur Query Produk dan Kategori

Penting untuk memahami flow resolver dan resolusi antar entitas. Berikut diagram mermaid sederhana.

MERMAID
graph TD
    A[Client] -- produkList query --> B[Query Resolver]
    B -- return array produk --> C[Produk Resolver]
    C -- resolve kategori field --> D[Kategori Resolver]
    D -- fetch Kategori dari produk.KategoriID --> E[KategoriData]

8. Tabel Relasional Produk-Kategori

ProdukKategori
LaptopElektronik
HPElektronik
Celana JeansFashion

9. Tips Production

  • Untuk data riil, ganti storage jadi database (PostgreSQL, MySQL, dsb), lalu abstract logic query di resolver.
  • Gunakan pattern DataLoader agar field resolver tidak N+1 (lihat gqlgen dataloader ).
  • Error handling dan validasi input pada mutation/query wajib ditingkatkan.
  • Pisahkan layer service & repository untuk scalability.

10. Kesimpulan

Kasus API produk-kategori ini adalah template yang sangat sering ditemukan di aplikasi nyata. Dengan gqlgen, kita bisa dengan mudah menyusun schema, resolvers, dan implementasi relasi data di GraphQL. Studi kasus singkat ini telah memperlihatkan struktur kode rapi, mock data sederhana, hingga simulasi query dan visualisasi data flow, yang bisa dengan mudah diadaptasi ke project yang lebih besar.

Semoga penjelasan ini membuka insight baru tentang pengaplikasian GraphQL di Golang untuk kebutuhan relasional data yang fleksibel dan skalabel.


Referensi


Bonus — Temukan repo kode contoh di sini (*if repo available)

Artikel Terkait

💬 Komentar