tutorial

13 Membuat Resolver Pertama di graphql-go

13 Membuat Resolver Pertama di graphql-go: Panduan Lengkap untuk Pemula

Jika kamu ingin membangun API modern yang fleksibel dan efisien, GraphQL sudah hampir wajib masuk ke dalam toolset developer masa kini. Berbeda dengan REST, GraphQL memungkinkan klien menentukan data apa saja yang ingin diambil dalam satu permintaan. Salah satu library paling populer di ekosistem Go adalah graphql-go, yang menawarkan cara straight-forward membangun GraphQL API di bahasa Go.

Dalam artikel ini, kita akan bahas secara langkah demi langkah proses membuat resolver pertama di graphql-go. Kita akan jelaskan konsepnya, implementasi dasar, menambahkan data simulasi, hingga membedah struktur kode dan alur eksekusinya, bahkan lengkap dengan contoh kode, simulasi, diagram alur, dan tabel hasil query.

Mari mulai!


Apa Itu Resolver di GraphQL?

Di GraphQL, resolver adalah fungsi yang bertugas memproses dan mengembalikan data untuk setiap field dalam schema. Setiap field pada Query, Mutation, maupun type lainnya akan dijalankan menggunakan fungsi resolver ini.

Analogi Sederhana

Jika schema adalah “struktur pertanyaan”, maka resolver adalah “cara menjawab” pertanyaan tersebut ke database, API lain, ataupun in-memory data.

Tabel: Perbandingan GraphQL Schema & Resolver

KomponenPeranContoh
SchemaMendefinisikan pertanyaantype Query { user(id:ID):User }
ResolverMenjawab pertanyaanfunc (r *Resolver) User(…) …

Langkah 1: Setup Project

Pertama, inisialisasi dulu project Go baru.

go mod init github.com/username/graphql-go-demo
go get github.com/graph-gophers/graphql-go
go get github.com/graph-gophers/graphql-go/relay

Langkah 2: Definisikan GraphQL Schema

Kita buat file schema.graphql:

type Query {
  hello: String!
  user(id: ID!): User
}

type User {
  id: ID!
  name: String!
  email: String!
}

Schema di atas memiliki:

  • Query hello yang mengembalikan string
  • Query user yang menerima argument id dan mengembalikan User dengan field id, name, dan email.

Langkah 3: Mode Simulasi Data

Buat data dummy (mock) pada file model.go:

package main

type User struct {
    ID    string
    Name  string
    Email string
}

// Simulasi database dummy
var users = []*User{
    {ID: "1", Name: "Alice", Email: "alice@example.com"},
    {ID: "2", Name: "Bob", Email: "bob@example.com"},
    {ID: "3", Name: "Charlie", Email: "charlie@example.com"},
}

Langkah 4: Membuat Resolver

Sekarang bagian menariknya: kita buat resolver yang menjodohkan schema GraphQL tadi dengan data Go kita.

Buat file resolver.go:

package main

import (
    "context"
)

type Resolver struct{}

func (r *Resolver) Hello(ctx context.Context) (string, error) {
    return "Halo dari resolver pertama!", nil
}

func (r *Resolver) User(ctx context.Context, args struct{ ID string }) (*userResolver, error) {
    for _, u := range users {
        if u.ID == args.ID {
            return &userResolver{u}, nil
        }
    }
    return nil, nil // atau bisa gunakan custom error
}

type userResolver struct {
    u *User
}

func (ur *userResolver) ID() string     { return ur.u.ID }
func (ur *userResolver) Name() string   { return ur.u.Name }
func (ur *userResolver) Email() string  { return ur.u.Email }

Catatan:

  • Setiap method (misal Hello, User) namanya HARUS kapital (exported) dan argumennya mengikuti urutan context.Context dulu, lalu argumen dari schema (jika ada).
  • Untuk type User, kita buat resolver sendiri (userResolver) karena graphql-go mengharuskan ada struct resolver per type yang pakai field.

Langkah 5: Setup HTTP Handler

Di main.go:

package main

import (
    "io/ioutil"
    "log"
    "net/http"

    "github.com/graph-gophers/graphql-go"
    "github.com/graph-gophers/graphql-go/relay"
)

func main() {
    schemaData, err := ioutil.ReadFile("schema.graphql")
    if err != nil {
        log.Fatalf("failed to read schema: %v", err)
    }

    schema := graphql.MustParseSchema(string(schemaData), &Resolver{})

    http.Handle("/graphql", &relay.Handler{Schema: schema})

    log.Println("GraphQL server listening at http://localhost:8080/graphql")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Langkah 6: Query Pertama ke Resolver

Jalankan server:

go run .

Coba gunakan tool seperti GraphiQL, Insomnia atau curl:

Query hello:

query {
  hello
}

Response:

{
  "data": {
    "hello": "Halo dari resolver pertama!"
  }
}

Query user:

query {
  user(id: "2") {
    id
    name
    email
  }
}

Response:

{
  "data": {
    "user": {
      "id": "2",
      "name": "Bob",
      "email": "bob@example.com"
    }
  }
}

Alur Eksekusi Resolver

Mari visualisasikan alurnya agar lebih mudah dipahami:

flowchart TD
    Client -->|Query| GraphQLServer
    GraphQLServer -->|Parse Schema| ResolverFunctions
    ResolverFunctions -->|Ambil Data| DatabaseSimulasi
    ResolverFunctions -->|Return| GraphQLServer
    GraphQLServer -->|Response JSON| Client

Penjelasan:

  1. Klien mengirim query ke endpoint GraphQL.
  2. Server melakukan parsing dan menemukan resolver sesuai field.
  3. Resolver mengeksekusi logic, mengambil data dari (simulasi) database.
  4. Data dikembalikan dalam format JSON sesuai permintaan klien.

Tabel: Simulasi Query User

QueryArgumenHasil
hello-“Halo dari resolver pertama!”
user(id: "1")id = “1”{“id”:“1”, “name”:“Alice”, …}
user(id: "3")id = “3”{“id”:“3”, “name”:“Charlie”, …}
user(id: "999")id = “999”null

Best Practice Resolver graphql-go

  1. Pisahkan antara schema, resolver, dan model. Ini agar kode tetap rapi dan mudah di-maintain.
  2. Gunakan context untuk propagasi data auth/logging, misal inject user ID atau trace ID dari header ke resolver.
  3. Testing resolver secara unit test dengan data mock untuk memastikan output sesuai ekspektasi.
  4. Mutasi data (misal create/update/delete) harus memakai Mutation, pola resolvernya mirip dengan Query.
  5. Error handling: Bachirkan error yang deskriptif, misal user tidak ditemukan, dan render ke klien dengan field errors di payload.

Kesimpulan

Membangun resolver di graphql-go sangatlah straightforward dan mengikuti prinsip-prinsip idiomatik Go. Dengan mengenal resolver, kita bisa dengan mudah mengatur bagaimana data diproses, diambil, dan dikembalikan sesuai permintaan klien. Model resolver seperti ini juga sangat mudah dikembangkan menjadi lebih kompleks: misal fetch data asinkron, agregasi data lintas service, atau memvalidasi akses user.

Dengan artikel ini, kamu sudah belajar bagaimana:

  • Menulis GraphQL schema dan mapping ke resolver Go
  • Membuat data simulasi dan query pertama di GraphQL endpoint
  • Memahami alur eksekusi resolver secara visual
  • Praktik best practice dasar dalam mengembangkan GraphQL API

Selamat mencoba membangun resolver pertamamu di graphql-go! Kalau ada pertanyaan atau saran topik lanjut, jangan sungkan bertanya di kolom komentar. 🚀


Referensi:


Happy coding! 👨‍💻👩‍💻

comments powered by Disqus

Topik Terhangat

programming
205
tutorial
72
tips-and-trick
43
jaringan
28
hardware
11
linux
4
kubernetes
1