tutorial

4 Arsitektur GraphQL Server dalam Go

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.mod
module monolith-graphql

go 1.18

require (
    github.com/99designs/gqlgen v0.17.24
)
# schema.graphqls
type Query {
  hello: String!
}
// resolver.go
package graph

type Resolver struct{}

func (r *Resolver) Query_hello() string {
    return "Hello from Monolithic GraphQL!"
}
// main.go
package main

import (
    "log"
    "net/http"
    "monolith-graphql/graph"
    "github.com/99designs/gqlgen/graphql/handler"
    "github.com/99designs/gqlgen/graphql/playground"
)

func main() {
    srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: &graph.Resolver{}}))
    http.Handle("/", playground.Handler("GraphQL playground", "/query"))
    http.Handle("/query", srv)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Diagram Alur

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):

graph
├── user/
│   ├── schema.graphqls
│   └── resolver.go
├── product/
│   ├── schema.graphqls
│   └── resolver.go
├── main.go
# user/schema.graphqls
type Query {
  user(id: ID!): User
}
type User { id: ID!, name: String! }
# product/schema.graphqls
type Query {
  product(id: ID!): Product
}
type Product { id: ID!, name: String! }
// main.go (fragment)
import (
    // ...
    "github.com/wundergraph/graphql-go-tools/pkg/executor"
    userSchema "yourapp/user/schema.graphqls"
    productSchema "yourapp/product/schema.graphqls"
)

func main() {
    mergedSchema := mergeSchemas(userSchema, productSchema)
    exec := executor.NewExecutor(mergedSchema)
    // Bind to HTTP handler
}

Diagram Alur

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:

// product/schema.graphqls
type Product @key(fields: "id") {
  id: ID!
  name: String!
}
extend type Query {
  product(id: ID!): Product
}
// user/schema.graphqls
type User @key(fields: "id") {
  id: ID!
  name: String!
  purchasedProducts: [Product]
}
extend type Query {
  user(id: ID!): User
}

Lalu masing-masing service dijalankan dengan server sendiri. Gateway membaca service registry dan komposisi schema secara otomatis (misal Apollo Gateway).

Diagram Alur

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:

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

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! 🚀

comments powered by Disqus