Sumber Daya
Sumber DayaPraktik terbaik GraphQL

Praktik terbaik GraphQL

GraphQL sudah cukup matang, dan telah hadir cukup lama, sehingga banyak artikel yang berbagi praktik terbaik telah diterbitkan oleh komunitas. Panduan-panduan ini mencakup hampir semua aspek GraphQL, termasuk desain skema, konvensi penamaan, penanganan keamanan, dan pemberian pesan kesalahan yang bermakna, di antara hal-hal lainnya.

Ini adalah beberapa panduan paling menarik tentang praktik terbaik dalam GraphQL.

Praktik terbaik di graphql.org

Situs resmi GraphQL menawarkan pengenalan umum tentang praktik terbaik dalam GraphQL.

Item-item ini sebagian besar mencakup perhatian tingkat atas, seperti:

Di mana lapisan GraphQL ditempatkan dalam arsitektur

Rekomendasi Lee Byron

Tidak lama setelah merilis GraphQL ke dunia, pencipta GraphQL Lee Byron menerbitkan artikel Lessons From 4 Years of GraphQL, yang menjelaskan bagaimana kita seharusnya secara konseptual berusaha bekerja dengan GraphQL:

  • Penamaan itu penting
  • Berpikir dalam grafik, bukan endpoint
  • Deskripsikan data, bukan tampilan
  • GraphQL adalah antarmuka tipis
  • Sembunyikan detail implementasi

Ia juga merinci beberapa prinsip dan pelajaran berharga yang dipelajarinya saat menggunakan GraphQL di Facebook.

GraphQL Rules

GraphQL Rules adalah situs yang secara khusus didedikasikan untuk menyajikan praktik terbaik sehari-hari dalam bekerja dengan GraphQL, terutama yang berkaitan dengan desain skema GraphQL.

Sumber daya ini sangat komprehensif. Ia mengkompilasi informasi dari beberapa sumber daya luar biasa yang ada (seperti artikel Designing GraphQL Mutations dan tutorial Shopify Designing a GraphQL API) dan menyajikan semuanya secara ringkas.

Aturan yang dijelaskan meliputi:

  1. Aturan penamaan
    • Gunakan camelCase untuk field dan argumen GraphQL.
    • Gunakan UpperCamelCase untuk tipe GraphQL.
    • Gunakan CAPITALIZED_WITH_UNDERSCORES untuk menamai tipe ENUM.
  2. Aturan tipe
    • Gunakan tipe skalar kustom jika ingin mendeklarasikan field atau argumen dengan nilai semantik tertentu.
    • Gunakan Enum untuk field yang berisi sekumpulan nilai tertentu.
  3. Aturan field (Output)
    • Gunakan nama semantik untuk field dan hindari kebocoran detail implementasi dalam nama field.
    • Gunakan field Non-Null jika field selalu memiliki nilai field yang diberikan.
    • Kelompokkan sebanyak mungkin field yang terkait ke dalam tipe Object kustom.
  4. Aturan argumen (Input)
    • Kelompokkan argumen yang saling terkait ke dalam input-type baru.
    • Gunakan tipe skalar ketat untuk argumen, misalnya DateTime daripada String.
    • Tandai argumen sebagai required, jika argumen tersebut diperlukan untuk eksekusi query.
  5. Aturan daftar
    • Untuk memfilter daftar, gunakan argumen filter yang berisi semua filter yang tersedia.
    • Gunakan argumen sort bertipe Enum atau [Enum!] untuk pengurutan daftar.
    • Gunakan limit dengan nilai default dan skip untuk membatasi jumlah item yang dikembalikan dalam daftar.
    • Gunakan argumen page, perPage untuk paginasi dan kembalikan tipe output dengan items (array elemen) dan pageInfo (meta-data).
    • Untuk daftar tak terbatas (infinite scroll) gunakan Relay Cursor Connections Specification.
  6. Aturan mutasi
    • Gunakan Namespace-types untuk mengelompokkan mutasi dalam satu resource.
    • Lampaui CRUD – buat mutasi kecil untuk operasi bisnis yang berbeda pada resource.
    • Pertimbangkan kemampuan melakukan mutasi pada beberapa item (perubahan batch pada tipe yang sama).
    • Mutasi harus mendeskripsikan secara jelas semua argumen wajib, tidak boleh ada opsi either-either.
    • Dalam mutasi, masukkan semua variabel ke dalam satu argumen input unik.
    • Setiap mutasi harus memiliki tipe payload yang unik.

Praktik terbaik resolver

Artikel GraphQL Resolvers: Best Practices menjelaskan cara terbaik membuat field resolver. Meskipun ditujukan untuk server Node.js (infrastruktur PayPal berbasis Express), beberapa pelajarannya juga dapat diterapkan untuk teknologi lain, termasuk PHP.

Poin-poin utama yang dapat dipetik:

  • Mengambil dan meneruskan data dari induk ke anak harus digunakan secukupnya.
  • Gunakan library seperti dataloader untuk menghapus duplikasi permintaan downstream.
  • Waspadai tekanan yang Anda timbulkan pada sumber data Anda.
  • Jangan mutasi "context". Memastikan kode yang konsisten dan lebih sedikit bug.
  • Tulis resolver yang dapat dibaca, dipelihara, dan diuji. Tidak terlalu rumit.
  • Buat resolver Anda setipis mungkin. Ekstrak logika pengambilan data ke fungsi async yang dapat digunakan kembali.

OWASP - GraphQL Cheat Sheet

OWASP (Open Web Application Security Project) adalah yayasan nirlaba yang bekerja untuk meningkatkan keamanan perangkat lunak. Ini melakukan penelitian tentang bagaimana berbagai teknologi rentan terhadap eksploitasi, dan menjelaskan solusi terhadap masalah keamanan secara menyeluruh, sehingga memudahkan pengembang untuk mencegah serangan.

OWASP telah menerbitkan GraphQL Cheat Sheet, yang menjelaskan serangan paling umum dan masalah keamanan terbesar dalam GraphQL, serta cara mengatasinya.

Serangan umum pada GraphQL meliputi:

  1. Injection - ini biasanya mencakup namun tidak terbatas pada:
    • SQL dan NoSQL injection
    • OS Command injection
    • SSRF dan CRLF injection/Request Smuggling
  2. DoS (Denial of Service)
  3. Penyalahgunaan otorisasi yang rusak: akses yang tidak tepat atau berlebihan, termasuk IDOR
  4. Batching Attacks, metode serangan brute force khusus GraphQL
  5. Penyalahgunaan konfigurasi default yang tidak aman

OWASP kemudian memberikan rekomendasi tentang cara menghindari masing-masing hal tersebut.

Praktik terbaik dengan queries GraphQL

Tim Apollo menerbitkan GraphQL query best practices, memberikan wawasan praktis tentang cara-cara praktis untuk menyusun query GraphQL.

Misalnya, kedua queries ini mencapai tujuan yang sama, tetapi karena yang pertama memiliki nama operasi, maka lebih mudah dipahami dan berguna saat debugging:

# Direkomendasikan ✅
query GetBooks {
  books {
    title
  }
}
 
# Tidak direkomendasikan ❌
query {
  books {
    title
  }
}

Saran-saran mereka meliputi:

  • Beri nama semua operasi
  • Gunakan variabel untuk menyediakan argumen GraphQL
  • Query hanya data yang Anda butuhkan, di tempat Anda membutuhkannya
  • Gunakan fragment untuk merangkum sekumpulan field yang terkait
  • Query data global dan data khusus pengguna secara terpisah

Memanfaatkan one graph

Juga dari tim Apollo adalah situs Principled GraphQL yang menjelaskan bahwa GraphQL bukan hanya sebuah spesifikasi tetapi, yang mungkin lebih penting, sebuah antarmuka untuk berinteraksi dengan "grafik" data dari perusahaan kita.

Melalui daftar 10 prinsip, situs ini menjelaskan cara memaksimalkan manfaat dari satu grafik:

  1. One Graph: Perusahaan Anda harus memiliki satu grafik terpadu, bukan beberapa grafik yang dibuat oleh masing-masing tim.
  2. Federated Implementation: Meskipun hanya ada satu grafik, implementasi grafik tersebut harus difederasikan di beberapa tim.
  3. Track the Schema in a Registry: Harus ada satu sumber kebenaran untuk mendaftarkan dan melacak grafik.
  4. Abstract, Demand-Oriented Schema: Skema harus berfungsi sebagai lapisan abstraksi yang memberikan fleksibilitas kepada konsumen sambil menyembunyikan detail implementasi layanan.
  5. Use an Agile Approach to Schema Development: Skema harus dibangun secara bertahap berdasarkan persyaratan aktual dan berkembang secara mulus dari waktu ke waktu.
  6. Iteratively Improve Performance: Manajemen kinerja harus menjadi proses berkelanjutan berbasis data, beradaptasi dengan mulus terhadap beban query dan implementasi layanan yang berubah.
  7. Use Graph Metadata to Empower Developers: Pengembang harus dilengkapi dengan kesadaran mendalam tentang grafik sepanjang seluruh proses pengembangan.
  8. Access and Demand Control: Berikan akses ke grafik berdasarkan per-klien, dan kelola apa dan bagaimana klien dapat mengaksesnya.
  9. Structured Logging: Tangkap log terstruktur dari semua operasi grafik dan manfaatkan sebagai alat utama untuk memahami penggunaan grafik.
  10. Separate the GraphQL Layer from the Service Layer: Adopsi arsitektur berlapis dengan fungsionalitas grafik yang dipecah menjadi lapisan terpisah daripada diintegrasikan ke setiap layanan.