Queries & Fields — GraphQL

Queries & Fields Query adalah cara membaca data di GraphQL. Kamu minta exact fields yang dibutuhkan — server mengembalikan JSON dengan shape yang sama. Basic…

Query adalah cara membaca data di GraphQL: kamu menulis field yang kamu mau, bertingkat sesuai hubungan datanya, dan server menjawab dengan JSON yang susunannya sama. Bayangin menitip catatan belanja ke teman: "Di toko buku, buku nomor 1: judul dan harga. Dari penulisnya: namanya saja." Teman pulang membawa catatan yang sama, tiap baris sudah terisi, gak ada tambahan yang gak kamu tulis.

🧪 Tebakan cepat: Kamu butuh judul buku 1 dan buku 2 dalam satu query, jadi kamu tulis book(id: 1) { title } lalu book(id: 2) { title }. Apa yang terjadi? Jawabannya ada di bagian "Alias: field yang sama dua kali".

Memilih field: selection set

Semua contoh memakai schema Toko Buku dari pelajaran sebelumnya. Query paling sederhana:

{
  book(id: 1) {
    title
    price
  }
}
{ "data": { "book": { "title": "Laskar Pelangi", "price": 89000 } } }

Hasilnya 58 byte. Bandingkan dengan GET /books/1 di REST yang selalu mengirim lima field (72 byte). Kalau cuma minta title, jawabannya tinggal 44 byte. Itu keuntungan utama memilih field: data yang gak dibutuhkan gak ikut terkirim, dan ini paling terasa di jaringan seluler.

Aturannya sama di schema mana pun: { user(id: 1) { name email } } mengembalikan name dan email dari user dengan id 1, gak lebih.

Dua aturan selection set:

Field bersarang

Field object bisa diisi field object lagi, sedalam yang schema izinkan. Penulis nomor 1 beserta bukunya:

{
  author(id: 1) {
    name
    books {
      title
      price
    }
  }
}
{
  "data": {
    "author": {
      "name": "Andrea Hirata",
      "books": [{ "title": "Laskar Pelangi", "price": 89000 }]
    }
  }
}

books adalah list ([Book!]!), jadi hasilnya array, dan selection set-nya berlaku untuk tiap buku di dalamnya.

Argument

Argument adalah nilai yang kamu kirim ke sebuah field, ditulis di dalam kurung setelah namanya. Field apa menerima argument apa, schema yang menentukan:

{
  books(status: IN_STOCK) {
    title
    stock
  }
}
{ "data": { "books": [{ "title": "Laskar Pelangi", "stock": 12 }, { "title": "Cantik Itu Luka", "stock": 5 }] } }

Alias: field yang sama dua kali

Dua book dengan argument berbeda di satu query akan berebut key yang sama di response, yaitu "book":

{
  book(id: 1) {
    title
  }
  book(id: 2) {
    title
  }
}

Server menolaknya:

{
  "errors": [
    {
      "message": "Fields \"book\" conflict because they have differing arguments. Use different aliases on the fields to fetch both if this was intentional.",
      "locations": [{ "line": 2, "column": 3 }, { "line": 5, "column": 3 }]
    }
  ]
}

Itu jawaban tebakannya: seluruh query ditolak, gak ada data. Solusinya alias, nama lain untuk key di response, ditulis namaBaru: field:

{
  laskar: book(id: 1) {
    title
  }
  bumi: book(id: 2) {
    title
    stock
  }
}
{
  "data": {
    "laskar": { "title": "Laskar Pelangi" },
    "bumi": { "title": "Bumi Manusia", "stock": 0 }
  }
}

Alias cuma mengganti nama key di response. Field yang dijalankan tetap book, dan tiap alias boleh memilih field yang berbeda.

__typename: nama type-nya

Tiap object punya field bawaan __typename yang berisi nama type-nya di schema. Field ini gak perlu ditulis di schema:

{
  book(id: 1) {
    __typename
    title
    author {
      __typename
      name
    }
  }
}
{ "data": { "book": { "__typename": "Book", "title": "Laskar Pelangi", "author": { "__typename": "Author", "name": "Andrea Hirata" } } } }

Ini berguna kalau satu field bisa berisi beberapa type (union dan interface), dan dipakai library seperti Apollo Client untuk menyimpan cache per type.

Field yang gak ada di schema

Field yang gak ada ditolak sebelum apa pun dijalankan. Kalau namanya mirip field yang ada, server memberi saran:

⚠️ Jebakan yang sering ketemu

📌 Nama operation dan urutan field

Operation boleh diberi nama: query BukuDetail { book(id: 1) { title } }. Hasilnya sama, tapi namanya muncul di log server dan devtools, jadi gampang dicari. Kalau satu dokumen berisi lebih dari satu operation, tiap operation wajib bernama, dan request harus menyebut mana yang dijalankan lewat operationName. Tanpa itu, server menjawab Must provide operation name if query contains multiple operations.

Urutan key di response mengikuti urutan field di query: { book(id: 1) { price title } } menjawab { "price": 89000, "title": "Laskar Pelangi" }. Nilai yang berubah-ubah, seperti id dari input pengguna, dikirim lewat variable, dibahas di pelajaran "Variables & Fragments".

TL;DR: Query membaca data: tulis field yang kamu mau, dan response-nya punya susunan yang sama, cuma berisi field itu (title saja = 44 byte, lawan 72 byte untuk /books/1). Field object wajib punya selection set { ... }, field scalar gak boleh. Field bisa bersarang (author { books { title } }), dan list menghasilkan array. Argument ditulis di kurung: wajib kalau bertanda !, dan cuma yang ada di schema. Dua field yang sama dengan argument berbeda butuh alias (laskar: book(id: 1)), kalau gak, seluruh query ditolak. __typename memberi nama type. Field yang gak ada ditolak, kadang dengan saran Did you mean.

Yang akan kamu pelajari