Apollo-link-rest: الإستراتيجية الموصى بها للتعامل مع أخطاء 404؟

تم إنشاؤها على ٦ يونيو ٢٠١٨  ·  12تعليقات  ·  مصدر: apollographql/apollo-link-rest


من الشائع جدًا أن تستخدم واجهة برمجة تطبيقات REST استجابة 404 للإشارة إلى عدم وجود سجل. في الوقت الحالي ، عندما يحدث هذا ، تكون النتيجة networkError والذي يبدو ، افتراضيًا ، أن يتم التعامل معه على أنه خطأ فادح أكثر من خطأ GraphQL بواسطة مكدس Apollo.

على سبيل المثال ، مع الاستعلام:

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

إذا قامت نقطة النهاية بإرجاع 404 ، فإنها ترفض مع وجود خطأ في الشبكة يجب معالجته حيث من المحتمل أن تستخدم النية خاصية التقديم error لعرض رسالة الخطأ غير الفادحة للمستخدم. على سبيل المثال ، إذا كان هذا استعلام GraphQL بدلاً من REST ، فلن يتم تصنيفه على أنه خطأ في الشبكة وسيتم التعامل معه بهذه الطريقة.

ما فعلته لإصلاح ذلك هو إضافة شيك إلى error-link المخصص الخاص بي والذي يحول خطأ الشبكة 404 إلى خطأ 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),
});

ربما لا يزال هناك مجال للتحسين في هذا الأمر ، لكنه يحل المشكلة.

كنت أتساءل عما إذا كان هذا يمكن / يجب معالجته بطريقة ما في apollo-link-rest ، لذلك اعتقدت أنني سأبدأ المحادثة.

enhancement💡 question❔

ال 12 كومينتر

هذا سؤال رائع. - أود إضافة هذا النمط كاقتراح للوثائق. أعتقد أنها فئة من المشكلات التي تعاني منها روابط أبولو المتعددة (تتبادر إلى الذهن حالة ارتباط أبولو).

لا أعلم أننا متأكدون من أن هذه هي الإجابة الصحيحة لجميع مستخدمي ApolloLink ، ولكن؟

هذه هي الطريقة التي يتم بها التعامل مع جميع أخطاء http حاليًا في 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;

ربما نضيف وظيفة مطابقة الحالة التي تتيح للمستخدمين إملاء كيفية معالجة الخطأ؟
يمكن أن يوفر بعض الأدوات المساعدة الافتراضية المفيدة للحالات الشائعة مثل 404 == null

بينما أشارك قلقfbartho من أن الحل الذي نقدمه قد لا يكون مناسبًا لجميع مستخدمي هذا الرابط ، فكرت في حالة واحدة يكون فيها الخطأ 404 ضارًا بشكل خاص. إذا أخذنا هذا المثال من الاختبارات:

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

و post غير موجود ويعيد 404 ثم يفشل الاستعلام بأكمله على خطأ في الشبكة. في حين أن هذا قد يكون مرغوبًا في بعض الحالات ، يبدو أن النتيجة يجب أن تكون:

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

إذا أردنا تلبية ذلك ، فإن إضافة معالجة أخطاء إضافية كما يقترح paulpdaniels ستكون سهلة للغاية. بالنظر إلى أخطاء 4xx ، يمكنني فقط رؤية 404 و 400/412/422 (على الطفرات) ربما تكون أخطاء غير فادحة تتطلب معالجة خاصة ، إما كأخطاء GraphQL أو تعيين النتيجة على null .

يبقى السؤال ما إذا كان من المعقول توفير بعض المعالج الثابت لهذه الأخطاء أو ما إذا كان ينبغي تركها لـ error-link أو التطبيق. نظرًا لأن استعلامات الطفرات المتعددة غير مدعومة (أعتقد؟) ، فإن المجيء القصير الحالي الوحيد الذي يبدو مناسبًا بشكل خاص هو المثال 404 الذي بدأت به أعلاه.

هناك أيضًا خيار إضافة معالج أخطاء إلى التكوين ، ولكن يبدو أن هذا قد يؤدي إلى سرقة الوظائف بعيدًا عن error-link الذي ينتمي حقًا إلى هناك. قد يؤدي أيضًا إلى جعل واجهة برمجة تطبيقات هذا الرابط معقدة بشكل غير ضروري.

marnusw هذا رد رائع. سأدعم إصلاحًا يطبق سلوكك افتراضيًا!

يضيف 142 معالجة خطأ 404. أعتقد أن هذا هو أهم شيء من هذه المناقشة.

استنادًا إلى العديد من معايير api للراحة ، يجب أن تتضمن جميع رموز الأخطاء دائمًا رسالة يمكن للبشر قراءتها. إن إبطال هذه النتيجة ، كما حدث في # 142 ، يتعارض بشكل مباشر مع ذلك.

لقد وضعت علاقات عامة لإعادة 404 إلى وضعها السابق كأخطاء شبكة عادية ، لتتوافق مع ممارسات واجهة برمجة تطبيقات REST الجيدة: https://github.com/apollographql/apollo-link-rest/pull/283

christrude بينما لا يمكنني الاختلاف معك فيما يتعلق بواجهات REST API ، فإن الغرض من هذه المكتبة هو جعل REST APIs تعمل مثل GraphQL. لذلك ، إذا كانت طريقة GraphQL للموارد المفقودة هي إرجاع null ، فيجب على هذه المكتبة تحويل اصطلاح RESTful 404 إلى اصطلاح قيمة الإرجاع GraphQL null .

christrude بينما لا يمكنني الاختلاف معك فيما يتعلق بواجهات REST API ، فإن الغرض من هذه المكتبة هو جعل REST APIs تعمل مثل GraphQL. لذلك ، إذا كانت طريقة GraphQL للموارد المفقودة هي إرجاع null ، فيجب على هذه المكتبة تحويل اصطلاح RESTful 404 إلى اصطلاح قيمة الإرجاع GraphQL null .

إذن كيف تقترح GraphQL التعامل مع استجابة 404 في واجهة المستخدم؟ لا تفعل شيئا؟ لذا تطلب فقط أن تموت بهدوء؟ هذه إدارة UX / api سيئة / سيئة بشكل لا يصدق.

إذا قمت بالاستعلام عن عنصر بواسطة المعرف وحصلت على قيمة فارغة ، فقم بالتعامل معها وفقًا لذلك في واجهة المستخدم. إذا كانت تحتوي على بيانات ، فقم بعرضها.

أتفق مع marnusw هنا ، لا يمكننا التحكم حقًا في ما تفعله واجهة برمجة تطبيقات المستخدم المتبقية ، لذا لا ينبغي أن تكون المكتبة مقيدة بشكل مفرط فيما تسمح به. 404 => التعيين الفارغ عبارة عن دلالات بديهية نسبيًا تتيح لك الانتقال من المورد الفردي لكل نموذج طلب في REST إلى المورد المتعدد لكل طلب (من منظور العميل) في GraphQL دون تفجير البيانات المفقودة.

ربما يمكن أن تكون هناك طريقة أفضل لإلغاء الاشتراك في هذا السلوك ، مثل إصدار معبأ مسبقًا من محول الاستجابة أو تجريد منطق معالجة الطلب الذي يتيح للمستخدم التحكم الكامل في معالجة حالة http. لكنني لا أعتقد أن العودة إلى السلوك السابق هو النهج الصحيح.

جزء من مشكلة النهج هو أنه في الجزء السفلي من الاشتراك في النتيجة ، لا تعرف ما إذا كانت النتيجة فارغة بسبب 404 ، أو إذا كانت النتيجة لا تحتوي على 201 أو شيء مشابه. لقد تم إصلاح هذا في البرامج اللاحقة ، والتحقق من الحالة وإجبارها على إلقاء خطأ يفترض المشكلة لأنني لا أستطيع الوصول إلى رسالة خطأ الخادم الفعلية ، خاصة في حالتي لأننا نستخدم الجلب المخصص لإدخال رمز المصادقة ، ولا يمكن استخدامه للحصول على الاستجابة قبل أن يحذفها أبولو. الحل الذي أقدمه هو غطاء سيئ لاستجابة 404 أخرى عبر التطبيق ، باستثناء الحالة الواحدة.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات