Saya memiliki kueri GraphQL yang dibungkus react-apollo berikut:

user(id: 1) {
  name
  friends {
    id
    name
  }
}

Seperti yang direpresentasikan secara semantik, ia mengambil pengguna dengan ID 1, mengembalikan name, dan mengembalikan id dan name dari semua temannya.

Saya kemudian membuat ini dalam struktur komponen seperti berikut:

graphql(ParentComponent)
  -> UserInfo
  -> ListOfFriends (with the list of friends passed in)

Ini semua bekerja untuk saya. Namun, saya ingin dapat mengambil kembali daftar teman untuk pengguna saat ini.

Saya dapat melakukan this.props.data.refetch() pada komponen induk dan pembaruan akan disebarkan; namun, saya tidak yakin ini adalah praktik terbaik, mengingat kueri GraphQL saya terlihat lebih seperti ini,

user(id: 1) {
  name
  foo1
  foo2
  foo3
  foo4
  foo5
  ...
  friends {
    id
    name
  }
}

Sementara satu-satunya hal yang ingin saya ambil kembali adalah daftar teman.

Apa cara terbaik untuk merancang ini dengan bersih? Saya sedang berpikir untuk mengikat pengambil GraphQL yang awalnya dilewati ke komponen ListOfFriends, yang dapat dipicu seperlunya, tetapi ingin beberapa panduan tentang cara terbaik untuk melakukannya.

Terima kasih sebelumnya.

10
Lucas 2 Januari 2018, 23:24

1 menjawab

Jawaban Terbaik

Saya tidak tahu mengapa pertanyaan Anda diturunkan karena saya pikir itu adalah pertanyaan yang sangat valid untuk ditanyakan. Salah satu nilai jual GraphQL adalah "mengambil lebih sedikit dan lebih banyak sekaligus". Seorang klien dapat memutuskan secara sangat rinci apa yang dibutuhkannya dari backend. Menggunakan kueri mirip grafik bersarang dalam yang sebelumnya memerlukan banyak titik akhir, kini dapat diekspresikan dalam satu kueri. Pada saat yang sama over-fetching dapat dihindari. Sekarang Anda menemukan diri Anda dengan kueri besar, semuanya dimuat sekaligus dan tidak ada n+1 kueri air terjun. Tetapi sekarang Anda tahu bahwa beberapa bidang dalam kueri besar Anda dapat berubah dari waktu ke waktu dan Anda ingin secara aktif memperbarui cache dengan data baru dari server. Apollo menawarkan bidang refetch tetapi memuat seluruh kueri yang jelas-jelas mengambil berlebihan yang dijual kepada saya karena tidak menjadi perhatian lagi di GraphQL. Izinkan saya menawarkan beberapa solusi:

Optimasi Prematur?

Masalah sebenarnya adalah bahwa programmer telah menghabiskan terlalu banyak waktu untuk mengkhawatirkan efisiensi di tempat yang salah dan pada waktu yang salah; optimasi prematur adalah akar dari semua kejahatan (atau setidaknya sebagian besar) dalam pemrograman. - Donald Knuth

Terkadang kita mencoba mengoptimalkan terlalu banyak tanpa mengukur terlebih dahulu. Tulis dengan cara yang mudah terlebih dahulu dan kemudian lihat apakah itu benar-benar masalah. Apa sebenarnya yang lambat? Jaringan? Bidang tertentu dalam kueri? Ukuran kueri yang tipis?

Setelah Anda menganalisis apa sebenarnya yang lambat, kami dapat mulai mencari peningkatan:

Ambil kembali dan sertakan/lewati arahan

Menggunakan direktif Anda dapat mengecualikan bidang dari kueri bergantung pada variabel. Fungsi pengambilan dapat menentukan variabel yang berbeda daripada permintaan awal. Dengan cara ini Anda dapat mengecualikan bidang saat Anda mengambil kueri.

Memisahkan Pertanyaan

Aplikasi satu halaman adalah ide bagus. HTML dihasilkan dari sisi klien dan halaman tidak harus melakukan perjalanan mahal ke server untuk merender halaman baru. Tapi segera SPA menjadi besar dan pemecahan kode menjadi masalah. Dan sekarang kita pada dasarnya kembali ke rendering sisi server dan membagi aplikasi menjadi beberapa halaman. Hal yang sama mungkin berlaku untuk GraphQL. Terkadang kueri terlalu besar dan harus dibagi. Anda dapat membagi kueri untuk UserInfo dan ListOfFriends. Di dalam cache, bidang akan digabungkan. Dengan pengumpulan kueri kedua kueri akan dikirim dalam permintaan yang sama dan server GraphQL yang mengimplementasikan caching sumber daya per permintaan dengan benar (misalnya dengan Dataloader) hampir tidak akan melihat perbedaan.

Langganan

Mungkin Anda sudah siap menggunakan langganan. Langganan mengirim pembaruan dari server untuk bidang yang telah berubah. Dengan cara ini Anda dapat berlangganan ke teman pengguna dan mendapatkan pembaruan secara real time. Kabar baiknya adalah bahwa Apollo Client, Relay, dan banyak implementasi server sudah menawarkan dukungan untuk langganan. Berita buruknya adalah ia membutuhkan soket web yang biasanya memberikan persyaratan berbeda pada tumpukan teknologi Anda daripada HTTP murni.

withApollo() -> this.client.query

Ini seharusnya hanya menjadi pilihan terakhir Anda! Dengan menggunakan komponen orde tinggi withApollo react-apollo withApollo, Anda dapat langsung menyuntikkan ApolloClient contoh. Anda sekarang dapat menjalankan kueri menggunakan this.client.query(). { user(id: 1) { friendlist { ... } } } dapat digunakan untuk hanya mengambil daftar teman dan memperbarui cache yang akan mengarah pada pembaruan komponen Anda. Ini mungkin terlihat seperti yang Anda inginkan tetapi dapat menghantui Anda di tahap aplikasi selanjutnya.

16
Herku 3 Januari 2018, 16:04