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
| Komponen | Peran | Contoh |
|---|---|---|
| Schema | Mendefinisikan pertanyaan | type Query { user(id:ID):User } |
| Resolver | Menjawab pertanyaan | func (r *Resolver) User(…) … |
Langkah 1: Setup Project
Pertama, inisialisasi dulu project Go baru.
1go mod init github.com/username/graphql-go-demo
2go get github.com/graph-gophers/graphql-go
3go get github.com/graph-gophers/graphql-go/relayLangkah 2: Definisikan GraphQL Schema
Kita buat file schema.graphql:
1type Query {
2 hello: String!
3 user(id: ID!): User
4}
5
6type User {
7 id: ID!
8 name: String!
9 email: String!
10}Schema di atas memiliki:
- Query
helloyang mengembalikan string - Query
useryang menerima argumentiddan mengembalikan User dengan fieldid,name, danemail.
Langkah 3: Mode Simulasi Data
Buat data dummy (mock) pada file model.go:
1package main
2
3type User struct {
4 ID string
5 Name string
6 Email string
7}
8
9// Simulasi database dummy
10var users = []*User{
11 {ID: "1", Name: "Alice", Email: "alice@example.com"},
12 {ID: "2", Name: "Bob", Email: "bob@example.com"},
13 {ID: "3", Name: "Charlie", Email: "charlie@example.com"},
14}Langkah 4: Membuat Resolver
Sekarang bagian menariknya: kita buat resolver yang menjodohkan schema GraphQL tadi dengan data Go kita.
Buat file resolver.go:
1package main
2
3import (
4 "context"
5)
6
7type Resolver struct{}
8
9func (r *Resolver) Hello(ctx context.Context) (string, error) {
10 return "Halo dari resolver pertama!", nil
11}
12
13func (r *Resolver) User(ctx context.Context, args struct{ ID string }) (*userResolver, error) {
14 for _, u := range users {
15 if u.ID == args.ID {
16 return &userResolver{u}, nil
17 }
18 }
19 return nil, nil // atau bisa gunakan custom error
20}
21
22type userResolver struct {
23 u *User
24}
25
26func (ur *userResolver) ID() string { return ur.u.ID }
27func (ur *userResolver) Name() string { return ur.u.Name }
28func (ur *userResolver) Email() string { return ur.u.Email }Catatan:
- Setiap method (misal
Hello,User) namanya HARUS kapital (exported) dan argumennya mengikuti urutancontext.Contextdulu, 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:
1package main
2
3import (
4 "io/ioutil"
5 "log"
6 "net/http"
7
8 "github.com/graph-gophers/graphql-go"
9 "github.com/graph-gophers/graphql-go/relay"
10)
11
12func main() {
13 schemaData, err := ioutil.ReadFile("schema.graphql")
14 if err != nil {
15 log.Fatalf("failed to read schema: %v", err)
16 }
17
18 schema := graphql.MustParseSchema(string(schemaData), &Resolver{})
19
20 http.Handle("/graphql", &relay.Handler{Schema: schema})
21
22 log.Println("GraphQL server listening at http://localhost:8080/graphql")
23 log.Fatal(http.ListenAndServe(":8080", nil))
24}Langkah 6: Query Pertama ke Resolver
Jalankan server:
1go run .Coba gunakan tool seperti GraphiQL
, Insomnia atau curl:
Query hello:
1query {
2 hello
3}Response:
1{
2 "data": {
3 "hello": "Halo dari resolver pertama!"
4 }
5}Query user:
1query {
2 user(id: "2") {
3 id
4 name
5 email
6 }
7}Response:
1{
2 "data": {
3 "user": {
4 "id": "2",
5 "name": "Bob",
6 "email": "bob@example.com"
7 }
8 }
9}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:
- Klien mengirim query ke endpoint GraphQL.
- Server melakukan parsing dan menemukan resolver sesuai field.
- Resolver mengeksekusi logic, mengambil data dari (simulasi) database.
- Data dikembalikan dalam format JSON sesuai permintaan klien.
Tabel: Simulasi Query User
| Query | Argumen | Hasil |
|---|---|---|
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
- Pisahkan antara schema, resolver, dan model. Ini agar kode tetap rapi dan mudah di-maintain.
- Gunakan context untuk propagasi data auth/logging, misal inject user ID atau trace ID dari header ke resolver.
- Testing resolver secara unit test dengan data mock untuk memastikan output sesuai ekspektasi.
- Mutasi data (misal create/update/delete) harus memakai Mutation, pola resolvernya mirip dengan Query.
- Error handling: Bachirkan error yang deskriptif, misal user tidak ditemukan, dan render ke klien dengan field
errorsdi 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! 👨💻👩💻