Apollo-link-rest: Strategi yang disarankan untuk menangani kesalahan 404?

Dibuat pada 6 Jun 2018  ·  12Komentar  ·  Sumber: apollographql/apollo-link-rest


REST API sangat umum menggunakan respons 404 untuk menunjukkan bahwa record tidak ada. Saat ini ketika ini terjadi, hasilnya adalah networkError yang tampaknya, secara default, diperlakukan sebagai kesalahan yang lebih fatal daripada kesalahan GraphQL oleh tumpukan Apollo.

Misalnya, dengan query:

query BookQuery($slug: ID!) {
  book(slug: $slug) @rest(type: "Book", path: "book/:slug") {
    name
    author
  }
}

Jika endpoint mengembalikan 404 itu menolak dengan kesalahan jaringan yang harus ditangani di mana maksud kemungkinan hanya menggunakan prop error render untuk menampilkan pesan kesalahan non-fatal kepada pengguna. yaitu jika ini adalah kueri GraphQL dan bukan REST, ini tidak akan diklasifikasikan sebagai kesalahan jaringan dan akan ditangani dengan cara ini.

Apa yang saya lakukan untuk memperbaikinya adalah menambahkan cek ke kustom error-link yang mengubah kesalahan jaringan 404 menjadi kesalahan GraphQL:

forward(operation).subscribe({
  next: result => {...},
  error: networkError => {
    if (networkError.statusCode === 404) {
      return observer.next({errors: [networkError]});
    }
    //...
    observer.error(networkError);
  },
  complete: observer.complete.bind(observer),
});

Mungkin masih ada ruang untuk perbaikan dalam hal ini, tetapi itu menyelesaikan masalah.

Saya bertanya-tanya apakah ini mungkin / entah bagaimana harus ditangani dalam apollo-link-rest , jadi saya pikir saya akan memulai percakapan.

enhancement💡 question❔

Semua 12 komentar

Itu pertanyaan yang bagus. - Saya ingin pola ini ditambahkan sebagai saran pada dokumentasi. Saya pikir ini adalah kelas masalah yang diderita banyak apollo-link (muncul dalam pikiran apollo-link-state).

Saya tidak tahu apakah kami yakin ini adalah jawaban yang tepat untuk semua pengguna ApolloLink?

Ini adalah cara bagaimana semua kesalahan http ditangani di apollo-link-rest

        if (res.status >= 300) {
          // Throw a JSError, that will be available under the
          // "Network error" category in apollo-link-error
          let parsed: any;
          try {
            parsed = await res.json();
          } catch (error) {
            // its not json
            parsed = await res.text();
          }
          rethrowServerSideError(
            res,
            parsed,
            `Response not successful: Received status code ${res.status}`,
          );
        }
        return res;

mungkin kami menambahkan fungsi pencocokan kasus yang memungkinkan pengguna menentukan bagaimana kesalahan diproses?
Dapat memberikan beberapa utilitas default yang berguna untuk kasus umum seperti 404 == null

Sementara saya berbagi kekhawatiran @fbartho bahwa solusi yang kami perkenalkan mungkin tidak tepat untuk semua pengguna tautan ini, saya memikirkan satu kasus di mana kesalahan 404 sangat berbahaya. Jika kita mengambil contoh ini dari pengujian:

query postAndTags {
  post @rest(type: "Post", path: "/post/1") {
    id
    title
  }
  tags @rest(type: "[Tag]", path: "/tags") {
    name
  }
}

dan post tidak ada dan mengembalikan 404 maka seluruh kueri gagal karena kesalahan jaringan. Meskipun itu mungkin diinginkan dalam beberapa kasus, tampaknya hasilnya lebih baik:

const data = {
  post: null,
  tags: [{ name: 'apollo' }, { name: 'graphql' }],
}

Jika kami ingin memenuhi ini, menambahkan penanganan error tambahan seperti yang disarankan @paulpdaniels akan sangat mudah. Melihat kesalahan 4xx, saya hanya dapat melihat 404 dan 400/412/422 (pada mutasi) mungkin merupakan kesalahan non-fatal yang memerlukan perlakuan khusus, baik sebagai kesalahan GraphQL atau menyetel hasilnya ke null .

Pertanyaannya tetap apakah masuk akal untuk menyediakan beberapa penangan tetap untuk kesalahan ini atau jika harus diserahkan pada error-link atau aplikasi. Karena beberapa kueri mutasi tidak didukung (menurut saya?), Satu-satunya kekurangan saat ini yang tampaknya sangat relevan adalah contoh 404 yang saya mulai dengan di atas.

Ada juga opsi untuk menambahkan penangan kesalahan ke konfigurasi, tetapi sepertinya itu bisa mencuri fungsionalitas dari error-link yang benar-benar seharusnya ada di sana. Mungkin juga membuat API tautan ini menjadi tidak perlu menjadi rumit.

@marnusw Itu tanggapan yang bagus. Saya akan mendukung perbaikan yang menerapkan perilaku Anda secara default!

142 menambahkan 404 penanganan error. Saya pikir itu yang paling penting dari diskusi ini.

Berdasarkan banyak standar rest api , semua kode kesalahan harus selalu menyertakan pesan yang dapat dibaca manusia. Membatalkan hasil itu, seperti yang dilakukan di # 142 adalah bertentangan langsung dengan itu.

Saya telah memasang PR untuk memulihkan 404 sebagai kesalahan jaringan normal, bertepatan dengan praktik API REST yang baik: https://github.com/apollographql/apollo-link-rest/pull/283

@christrude sementara saya tidak bisa tidak setuju dengan Anda sejauh menyangkut REST API, tujuan pustaka ini adalah membuat REST API berfungsi seperti GraphQL. Oleh karena itu, jika pendekatan GraphQL untuk sumber daya yang hilang adalah mengembalikan null , maka pustaka ini harus mengonversi konvensi RESTful 404 ke konvensi nilai pengembalian GraphQL null .

@christrude sementara saya tidak bisa tidak setuju dengan Anda sejauh menyangkut REST API, tujuan pustaka ini adalah membuat REST API berfungsi seperti GraphQL. Oleh karena itu, jika pendekatan GraphQL untuk sumber daya yang hilang adalah mengembalikan null , maka pustaka ini harus mengonversi konvensi RESTful 404 ke konvensi nilai pengembalian GraphQL null .

Lalu bagaimana GraphQL mengusulkan Anda menangani respons 404 di UI? Tidak melakukan apapun? Jadi permintaan mati diam-diam? Itu manajemen UX / api yang sangat buruk / buruk.

Jika Anda membuat kueri item berdasarkan ID dan mendapatkan kembali null, tangani hal itu di UI. Jika itu berisi data, maka tampilkanlah.

Saya setuju dengan @marnusw di sini, kami tidak dapat benar-benar mengontrol apa yang dilakukan API istirahat pengguna sehingga pustaka tidak boleh terlalu membatasi apa yang diizinkannya. Pemetaan 404 => null adalah semantik yang relatif intuitif yang memungkinkan Anda berpindah dari sumber daya tunggal per model permintaan REST ke multi-sumber daya per permintaan (dari perspektif klien) GraphQL sambil tidak meledakkan data yang hilang.

Mungkin ada cara yang lebih baik untuk menyisih dari perilaku ini, seperti versi transformator respons yang sudah dikemas sebelumnya atau abstraksi dari logika penanganan permintaan yang memungkinkan pengguna mengontrol sepenuhnya penanganan status http. Tetapi menurut saya, mengembalikan ke perilaku sebelumnya bukanlah pendekatan yang tepat.

Bagian dari masalah pendekatan ini adalah bahwa di hasil langganan Anda tidak memiliki pengetahuan apakah hasilnya nol karena ini adalah 404, atau jika tidak ada konten yang mengembalikan 201 atau yang serupa. Saya telah memperbaikinya dengan di afterware, memeriksa status dan memaksanya untuk melakukan kesalahan yang mengasumsikan masalah karena saya tidak dapat mengakses pesan kesalahan server yang sebenarnya, terutama dalam kasus saya karena kami menggunakan pengambilan khusus untuk menyuntikkan token autentikasi , dan tidak bisa menggunakannya untuk mendapatkan respons sebelum apollo menghapusnya. Solusi saya adalah selimut yang buruk untuk respons 404 lainnya di seluruh aplikasi, selain dari satu kasus.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat