graphql - jebakan

Mungkin tidak ada teknologi yang sempurna. Graphql tidak terkecuali. Jika Anda belum memiliki pengalaman dengan teknologi ini, maka Anda harus memiliki ide bagus tentang masalah apa yang mungkin Anda miliki dan mempersiapkannya terlebih dahulu.

Untuk mulai dengan, saya akan mengatakan bahwa saya lebih mendukung daripada musuh menggunakan graphql di mana mungkin. Dan saya tidak akan menghalangi siapa pun tentang kelayakan menggunakan teknologi ini. Dan itulah mengapa saya mengajukan pertanyaan yang berhubungan dengan masalah yang belum terselesaikan dalam kerangka teknologi graphql.

Misalnya, untuk seseorang mungkin tidak terduga bahwa setiap objek dalam graphql harus dideskripsikan setidaknya dua kali: sekali sebagai tipe pengembalian objek, dan sekali lagi sebagai tipe input objek (lihat graphql.org/graphql-js/mutations- dan-input-type ). Namun, saya mengatakan ini sebagai permulaan dan bahkan tidak menganggapnya sebagai kelemahan yang signifikan. Hari ini kita akan fokus pada masalah-masalah seperti itu, sebagai suatu peraturan, harus diselesaikan ketika mengembangkan aplikasi menggunakan teknologi graphql:

  1. Pemisahan akses untuk pengguna dan grup pengguna.
  2. Menangani kesalahan.
  3. PILIH N + 1 Masalah

Pemisahan akses untuk pengguna dan grup pengguna


graphql tidak tahu apa-apa tentang berbagi akses antara pengguna dan grup. Dengan demikian, semua pekerjaan berbagi akses adalah tanggung jawab pengembang aplikasi. Parameter ketiga melewati objek konteks aplikasi ke fungsi resolver. Oleh karena itu, jika Anda, misalnya, bekerja dengan implementasi graphql JavaScript + express, maka dalam parameter konteks Anda bisa mendapatkan pengguna saat ini dari objek express.js permintaan. Tetapi pekerjaan lebih lanjut tentang kontrol akses harus dilakukan secara langsung di setiap resolver:

function(root, {id}, ctx) { return DB.Lists.get(id) .then( list => { if(list.owner_id && list.owner_id != ctx.userId){ throw new Error("Not authorized to see this list"); } else { return list; } }); } 

Secara alami, pendekatan ini mempersulit kontrol akses karena tidak ada cara untuk menetapkan hak akses secara deklaratif, dan kontrol hak tersebar di lebih dari puluhan (untuk beberapa sistem besar, lebih dari ribuan) fungsi penyelesai. Oleh karena itu, ada sejumlah perpustakaan yang memecahkan masalah ini. Beberapa dari mereka cukup populer (dilihat dari jumlah bintang di github.com), misalnya github.com/maticzav/graphql-shield .

Menangani kesalahan


Jika frontend Anda memerlukan validasi input dan pembuatan pesan terperinci untuk setiap bidang yang belum lulus validasi, maka penanganan kesalahan dalam graphql kemungkinan besar tampaknya tidak cukup fleksibel untuk Anda. Misalnya, jika parameter input dijelaskan sebagai string, dan nilai numerik diterima, maka pesan kesalahan akan sedikit digunakan untuk ini:

 { "errors": [ { "message": "Expected type String, found 1.", "locations": [ { "line": 2, "column": 15 } ] } ] } 

Jika ada kesalahan kotor dalam jenis parameter input, maka pesan kesalahan akan dihasilkan secara otomatis dan tidak ada cara untuk mengontrol proses ini. Jika validasi berdasarkan jenis parameter input berhasil, maka dimungkinkan untuk mengirim pesan kesalahan khusus ke klien dengan melemparkan objek new Error ('custom message ...') . Ini tidak akan berfungsi untuk menambahkan bidang khusus ke objek kesalahan (kustomisasi kesalahan diimplementasikan di pustaka apollo-server-express dan apollo-error saat digunakan bersama-sama). Tentu saja, selalu ada kesempatan untuk membuat cerita bersambung objek menjadi string message di server dan membatalkan deserialisasi pada klien. Tetapi apakah perlu untuk melakukannya?

PILIH N + 1 Masalah


Masalah ini dibahas secara rinci dalam pesan .

graphql dibangun di atas fungsi resolver. Ini berarti bahwa mengambil data dari database dapat menyebabkan masalah yang disebut SELECT N +1. Misalkan dalam fungsi resolver daftar objek diperoleh di mana data yang terkait dengan objek ini diwakili oleh pengidentifikasi (kunci asing). Untuk setiap pengenal tersebut, pemecah fungsi sendiri akan dipanggil, di mana (di masing-masing) permintaan tambahan ke database akan dibuat. Jadi, alih-alih permintaan basis data tunggal (dengan SQL BERGABUNG), banyak kueri akan dieksekusi, yang membebani database dengan kueri.

Untuk mengatasi masalah ini, facebook mengembangkan pustaka github.com/graphql/dataloader , yang menggunakan strategi permintaan yang tertunda. Alih-alih mengeksekusi permintaan secara langsung di resolver fungsi, ia diusulkan untuk mengakumulasikan pengidentifikasi (kunci sekunder) dalam array, dan kemudian menerimanya langsung dengan satu permintaan.

apapacy@gmail.com
13 Mei 2019

Source: https://habr.com/ru/post/id451466/


All Articles