Apollo-link-rest: Cara elegan untuk mengantri permintaan server istirahat? Konkurensi maksimum, jarak waktu, pelambatan ?

Dibuat pada 20 Jan 2019  Β·  7Komentar  Β·  Sumber: apollographql/apollo-link-rest

Saya menggunakan apollo-link-rest untuk membuat panggilan ke api istirahat pihak ke-3 gratis. Saya pikir ini adalah kasus penggunaan yang bagus.

Namun, seperti yang kita semua tahu api pihak ke-3 harus ditangani dengan _menghormati konkurensi permintaan & celah keamanan minimum antara permintaan api berturut-turut_. Yaitu memastikan Anda menekan server tidak lebih sering dari setiap 100ms.

Saat apollo mengambil alih panggilan, saya bertanya-tanya apakah ada cara yang bagus untuk menyebarkan panggilan dari waktu ke waktu ? Secara tidak sengaja, tidak perlu banyak waktu untuk membuat kueri yang memicu permintaan tambahan untuk menyelesaikan permintaan penuh. Misalnya dengan menggunakan direktif @export .

_Dua panggilan sekaligus_

const QUERY = gql`
  query RestData($email: String!) {
    # 1) Query for user πŸš€
    users @rest(path: '/users/email?{args.email}', method: 'GET', type: 'User') {
      id @export(as: "id")
      firstName
      lastName
      # 2) Sub query for friends fires immediately as well πŸš€
      friends @rest(path: '/friends/{exportVariables.id}', type: '[User]') {
        firstName
        lastName
      }
    }
  }
`;

Untuk mengurangi kasus ringan dari masalah kueri n+1 (yaitu mengambil semua produk, daripada setiap deskripsi produk), saya ingin memiliki jaring pengaman untuk kesalahan server 429 (gagal karena pembatasan kecepatan dari server).

_Apa yang saya lakukan sekarang: Membungkus fetch_

const restProviders = new RestLink({
  endpoints: {
    mySlowEndpoint: baseUrl
  },
  customFetch: (...args) =>
    new Promise((resolve, reject) => {
      // πŸš™βŸ·πŸš•βŸ·πŸš— Implementing my queue logic to fire of fetches
        resolve(fetch(...args));
      // when enough time has elapsed. πŸš™βŸ·πŸš•βŸ·πŸš— 
    })
})

Saat ini saya sedang membungkus proses pengambilan dalam logika antrian khusus, tetapi apakah ada "cara yang lebih elegan" untuk mengintegrasikan ini? Saya yakin, banyak orang akan tertarik untuk memiliki kendali atas beban keluar tanpa harus langsung membuat kueri gagal.

Komentar yang paling membantu

Mungkin saya harus menambahkan apa yang saya lakukan sekarang untuk orang lain yang datang dari google. Saat ini saya menggunakan p-throttle ( repo ).

// (...)
import pThrottle from "p-throttle";

const restProviders = new RestLink({
  endpoints: {
    mySlowEndpoint: baseUrl
  },
  // Throttle fetches to max 1 concurrent request πŸš€ and
  //  min. delay of 0.5 seconds πŸš™βŸ·πŸš•βŸ·πŸš— .
  customFetch: pThrottle( (...args) => {
    return fetch(...args);
  }, 1, 500)
})

// (...)

Semua 7 komentar

Mungkin saya harus menambahkan apa yang saya lakukan sekarang untuk orang lain yang datang dari google. Saat ini saya menggunakan p-throttle ( repo ).

// (...)
import pThrottle from "p-throttle";

const restProviders = new RestLink({
  endpoints: {
    mySlowEndpoint: baseUrl
  },
  // Throttle fetches to max 1 concurrent request πŸš€ and
  //  min. delay of 0.5 seconds πŸš™βŸ·πŸš•βŸ·πŸš— .
  customFetch: pThrottle( (...args) => {
    return fetch(...args);
  }, 1, 500)
})

// (...)

@ D1no Saya akan menyarankan customFetch, tetapi Anda sudah melakukannya!

Saya tidak yakin ini benar-benar fitur yang dapat dikonfigurasi langsung dari Apollo-link-rest, tetapi saya akan mendukung menyertakan cuplikan seperti ini di dokumen.

Bisakah Anda mengarahkan saya ke tempat yang bagus di dokumen untuk PR informasi ini sebagai contoh apa yang dapat dilakukan dengan customFetch? Saya pikir Anda benar; melemparkan konfigurabilitas seperti itu ke dalam apollo-link-rest akan menggabungkan metodologi pengambilan yang tidak terlalu elegan.

Dalam PR saya akan mengeluarkan p-antrian untuk contoh yang lebih dibuat-buat untuk pemula yang membaca. Siapa pun yang serius menggunakan apollo-link-rest sebagai obat gerbang-jalan ke GraphQL akan membutuhkan _beberapa manajemen konkurensi / debouncing_ di beberapa titik.

Hai @D1no , Anda dapat menemukan sini . Saya sarankan itu harus berada di judul Options , di atas Complete options .

Terima kasih @tombarton. Melihat lebih dekat pada masalah lagi, mungkin ide yang baik untuk dapat memiliki opsi throttle sederhana untuk panggilan pengambilan.

Meskipun saya awalnya mengatakan pengambilan koplingnya, sebenarnya itu tidak benar. Ini adalah panggilan untuk (sewenang-wenang) mengambil metodologi yang merajalela di sini. Untuk dapat menjinakkan apollo-link-rest secara membabi buta/eksekusi yang bersemangat, beberapa opsi konkurensi dan batas ms sederhana seperti yang terlihat di atas , mungkin bukan ide yang buruk pada akhirnya.

const restProviders = new RestLink({
  endpoints: {
    mySlowEndpoint: baseUrl
  },
  maxConcurrency: 2 // Max Concurrency πŸš€πŸš€
  minThrottle: 500 // Handling Rate Limit in ms πŸš™βŸ·πŸš•βŸ·πŸš— 
})

dan/atau dapat menentukannya dalam kueri

const QUERY = gql`
  query RestData($email: String!) {
    users @rest(path: '/users/email?{args.email}', method: 'GET', type: 'User') {
      id @export(as: "id")
      firstName
      lastName
      # NEW:       β€₯ πŸš™βŸ·πŸš•     β€₯ πŸš€πŸš€
      friends @rest(throttle: 500, concurrency: 2, path: '/friends/{exportVariables.id}', type: '[User]') {
        firstName
        lastName
      }
    }
  }
`;

Lagi pula, mengapa metodologi pengambilan harus mengatur seberapa sering dipanggil (seharusnya tidak peduli apa yang terjadi di lantai atas). Saya akan berpikir sedikit tentang itu. Bagaimanapun, customFetch harus melewati beberapa informasi tentang kueri saat ini dan bukan hanya permintaan kosong (untuk dapat membuat keputusan cerdas jika orang benar-benar membutuhkannya).

Mungkin salah satu pengelola/staf (@fbartho) bisa ikut campur? Saya akan dengan senang hati meluangkan waktu untuk PR jika manfaatnya disetujui.

@ D1no sejujurnya saya menyukai saran Anda untuk memasukkan dokumen. -- Antrian adalah kebalikan dari cara kami ingin melakukan sesuatu di aplikasi perusahaan kami. (Deduplikasi adalah salah satu yang saya buat, misalnya).

Secara terpisah, karena titik akhir bisa sangat berbeda, saya ragu untuk menetapkan "maxConcurrency/minThrottle" sebagai masalah global.

ApolloLinkRest adalah tentang "memasukkan barang ke Apollo" -- kekhawatiran yang telah Anda gambarkan ini benar-benar terasa seperti seharusnya berada di lapisan Jaringan alias pengambilan khusus. -- Selain itu, saya merasa tidak mungkin Anda ingin menyesuaikan nilai-nilai ini untuk setiap jalur kueri, jadi menyematkan pengaturannya di GraphQL tampaknya berisik.

Baiklah β€” saya akan PR tambahan untuk dokumentasi terlebih dahulu. Kita harus menurunkan customFetch terlebih dahulu sebelum mengoleskan lapisan di atasnya.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

karensg picture karensg  Β·  5Komentar

Simply007 picture Simply007  Β·  5Komentar

genomics-geek picture genomics-geek  Β·  3Komentar

sinisterra picture sinisterra  Β·  6Komentar

fkolar picture fkolar  Β·  5Komentar