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

4 Arsitektur GraphQL Server dalam Go

IH
Ihsan Arif
Penulis di Santekno · Backend Engineer

4 Arsitektur GraphQL Server dalam Go

GraphQL telah menjadi standar baru dalam membangun API yang scalable dan fleksibel. Ekosistem Go (Golang) sendiri, meskipun identik dengan REST, sebenarnya sudah menyediakan banyak pilihan tools dan arsitektur untuk membangun GraphQL server yang production-ready.

Dalam artikel ini, saya akan membahas empat arsitektur GraphQL server yang umum digunakan di Go, lengkap dengan contoh kode, simulasi, serta diagram alur menggunakan Mermaid agar visualisasinya lebih mudah dipahami.


1. Monolithic GraphQL Server

Deskripsi
Arsitektur monolitik adalah pola paling sederhana—semua business logic, resolver, dan data access berada dalam satu codebase/service. Untuk Go, library populer seperti graph-gophers/graphql-go atau 99designs/gqlgen biasanya dipakai.

Kapan digunakan:

  • Project skala kecil hingga menengah
  • Tim kecil
  • MVP atau prototyping

Keunggulan:

  • Mudah dikembangkan dan di-deploy
  • Overhead kecil
  • Debugging sederhana

Kekurangan:

  • Sulit diskalakan
  • Tight coupling antara resolver dan data

Contoh kode sederhana (menggunakan gqlgen):

go
1// go.mod
2module monolith-graphql
3
4go 1.18
5
6require (
7    github.com/99designs/gqlgen v0.17.24
8)
graphql
1# schema.graphqls
2type Query {
3  hello: String!
4}
go
1// resolver.go
2package graph
3
4type Resolver struct{}
5
6func (r *Resolver) Query_hello() string {
7    return "Hello from Monolithic GraphQL!"
8}
go
 1// main.go
 2package main
 3
 4import (
 5    "log"
 6    "net/http"
 7    "monolith-graphql/graph"
 8    "github.com/99designs/gqlgen/graphql/handler"
 9    "github.com/99designs/gqlgen/graphql/playground"
10)
11
12func main() {
13    srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: &graph.Resolver{}}))
14    http.Handle("/", playground.Handler("GraphQL playground", "/query"))
15    http.Handle("/query", srv)
16    log.Fatal(http.ListenAndServe(":8080", nil))
17}

Diagram Alur

MERMAID
graph TD;
    User-->GraphQLServer
    GraphQLServer-->Resolver
    Resolver-->Database

2. Schema Stitching

Deskripsi
Jika API Anda mulai besar dan terdiri dari banyak domain (user, product, payment), Anda bisa memisahkan schema dan logic-nya ke beberapa module, lalu di-combine menggunakan schema stitching. Pada Go, graphql-go-tools dari WunderGraph atau gqlmerge bisa digunakan untuk melakukan stitching.

Kapan digunakan:

  • Team besar dengan domain berbeda
  • Kodebase ingin modular
  • Scaling secara team/organisasi

Keunggulan:

  • Mudah di-maintain per domain
  • Dapat re-use modul schema

Kekurangan:

  • Registrasi resolver lebih rumit
  • Versi dan dependensi harus dikontrol

Contoh kode (simulasi pattern modular):

text
1graph
2├── user/
3│   ├── schema.graphqls
4│   └── resolver.go
5├── product/
6│   ├── schema.graphqls
7│   └── resolver.go
8├── main.go

graphql
1# user/schema.graphqls
2type Query {
3  user(id: ID!): User
4}
5type User { id: ID!, name: String! }
graphql
1# product/schema.graphqls
2type Query {
3  product(id: ID!): Product
4}
5type Product { id: ID!, name: String! }
go
 1// main.go (fragment)
 2import (
 3    // ...
 4    "github.com/wundergraph/graphql-go-tools/pkg/executor"
 5    userSchema "yourapp/user/schema.graphqls"
 6    productSchema "yourapp/product/schema.graphqls"
 7)
 8
 9func main() {
10    mergedSchema := mergeSchemas(userSchema, productSchema)
11    exec := executor.NewExecutor(mergedSchema)
12    // Bind to HTTP handler
13}

Diagram Alur

MERMAID
graph TB;
    User-->UserService
    Product-->ProductService
    UserService-->SchemaStitchingLayer
    ProductService-->SchemaStitchingLayer
    SchemaStitchingLayer-->Client

3. Federation (Apollo Federation Inspired)

Deskripsi
Federation adalah arsitektur di mana masing-masing domain/service memiliki GraphQL server sendiri dengan schema yang composable. Lalu, ada satu Gateway (Apollo Gateway, atau implementasi sendiri di Go) yang merge schema dan menjadi entrypoint utama client.

Di Go, Anda dapat menggunakan gqlgen-federation .

Kapan digunakan:

  • Microservices
  • Ownership per domain
  • Multi-team/organization

Keunggulan:

  • Scalability
  • Independence per tim/domain
  • Bisa deploy service tanpa men-downtime gateway

Kekurangan:

  • Lebih kompleks (infra & devops)
  • Consistency dan dependency antar service
  • Latency meningkat jika chain antar service panjang

Contoh Kode Simulasi:

go
1// product/schema.graphqls
2type Product @key(fields: "id") {
3  id: ID!
4  name: String!
5}
6extend type Query {
7  product(id: ID!): Product
8}
go
1// user/schema.graphqls
2type User @key(fields: "id") {
3  id: ID!
4  name: String!
5  purchasedProducts: [Product]
6}
7extend type Query {
8  user(id: ID!): User
9}
Lalu masing-masing service dijalankan dengan server sendiri. Gateway membaca service registry dan komposisi schema secara otomatis (misal Apollo Gateway).

Diagram Alur

MERMAID
graph TD;
    Client-->GraphQLGateway
    GraphQLGateway-->UserGraphQLService
    GraphQLGateway-->ProductGraphQLService

4. BFF (Backend for Frontend) Pattern

Deskripsi
BFF adalah pattern di mana satu GraphQL server didesain khusus untuk kebutuhan specific frontend/app (misal: mobile vs web). GraphQL di Go sering digunakan sebagai layer agregasi data dari berbagai backend (REST, RPC, DB, dsb).

Kapan digunakan:

  • Satu frontend dengan kebutuhan unik
  • Ingin lakukan agregasi multiple backend
  • Optimalisasi query/response untuk satu consumer

Keunggulan:

  • Highly tailored API untuk satu frontend
  • Bisa optimasi security dan caching
  • Field usage tracking lebih terpantau

Kekurangan:

  • Tidak reusable antar frontend
  • Harus sync schema jika ada frontend baru

Contoh Kode:
Kita akan agregasi data dari REST API dan database, lalu expose dengan GraphQL:

go
 1// resolver.go (pseudo code)
 2func (r *Resolver) Query_user(ctx context.Context, id string) (*User, error) {
 3    // Fetch dari REST
 4    resp, _ := http.Get(fmt.Sprintf("https://api.mycompany.com/users/%s", id))
 5    var userData User
 6    json.NewDecoder(resp.Body).Decode(&userData)
 7    
 8    // Fetch dari DB (misal, list order)
 9    orders := db.GetOrdersForUser(id)
10    return &User{...userData, Orders: orders}, nil
11}

Simulasi Perbandingan (Tabel)

PatternTopologiKapan DigunakanScalabilityEasiest to Build?Suitability
MonolithSingle serviceSmall project, MVPLowYesTight team, low overhead
Schema StitchingModular, 1 processMedium-large, domain specMediumMediumSeveral domains, team
FederationMicroservices + GatewayOrg-wide, multi-productHighNoLarge org, microservices
BFF1:1 for each frontendPer app/frontendMediumMediumTailored, per app

Penutup

Membangun GraphQL server di Go sangat fleksibel—Anda bisa mulai dari monolith, lantas re-factor ke modular, federation, atau BFF tergantung kebutuhan bisnis dan pertumbuhan tim.

Rule of thumb:

  • Mulai dari yang sederhana, evolve ke pola lebih kompleks jika skala dan kebutuhan bertambah.
  • Go sangat capable untuk production GraphQL—pilihlah library dan arsitektur sesuai fase project dan kompetensi tim.

Referensi


Saran? Masukan? Pengalaman migrate arsitektur GraphQL di Go? Silakan berbagi di kolom komentar!


Happy coding! 🚀

Artikel Terkait

💬 Komentar