API - الطلبات المتعددة مقابل أدوار المستخدم المنفصلة

StackOverflow https://stackoverflow.com//questions/25062443

سؤال

أنا أعمل على الواجهة الأمامية لتطبيق من صفحة واحدة ولا بد لي من إدراج عدد من الطلاب.كل طالب مرتبط بشيء معين user_id هذا هو ما تُرجعه واجهة برمجة التطبيقات (API) لجميع أدوار المستخدمين (المسؤول المتميز، المشرف، الأستاذ، الطالب) عندما أقوم بالأداء GET /students:

{
  address: null
  class_id: 184
  class_name: "I B"
  date_of_birth: null
  first_name: "first"
  gender: null
  grade: 1
  id: 192
  last_name: "last"
  nationality: null
  place_of_birth: null
  ranking_by_class: 0
  ranking_by_school: 0
  registration_number: null
  user_id: 238
}

أنا أعمل على دور المشرف المتميز في الوقت الحالي حيث أحتاج إلى بيانات إضافية من كل طالب (subscription_type)، وهو متاح فقط على GET /users/:id

لذلك عندما أقوم بإدراج 20-30 طالبًا في الصفحة عبر GET /students/, ، من أجل الحصول على subscription_type, ، سأحتاج أيضًا إلى تنفيذ 20-30 طلبًا إضافيًا، طلبًا واحدًا لكل طالب.

لقد تحدثت إلى مسؤول واجهة برمجة التطبيقات (API) حول هذا الأمر وقيل لي أنه يجب تضمين البيانات الإضافية في هذا الأمر students "ليست طريقة RESTful للقيام بذلك"، "وسوف تؤدي إلى إبطاء أوقات الاستجابة بشكل أكبر" وأن "30 طلبًا إضافيًا تزن أقل من قطعة كبيرة".

لا أعرف أي شيء عن العمل على واجهة برمجة التطبيقات (API)، لذا لا يمكنني حقًا أن أقول رأيي، ولكن هل أنا مجنون للاعتقاد بأن 30 طلبًا عند تحميل الصفحة أمر مثير للسخرية؟

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

هل كانت مفيدة؟

المحلول

على الرغم من أن رجل واجهة برمجة التطبيقات (API) صحيح بالمعنى الدقيق للكلمة، إلا أن اتباع إنجيل RESTful بشكل صارم للغاية يمكن أن يؤدي إلى عدم الكفاءة مثل مشكلة 1+N التي أنشأها التنفيذ النقي.أحد المفاهيم الأساسية في تصميم RESTful هو أن الموارد لا يلزم تعيينها مباشرة إلى كائنات المجال.عند تصميم الموارد يجب على المرء أن ينظر إلى سيناريوهات الاستخدام.في سيناريو المشرف المتميز، يبدو الأمر كما لو أن العميل يطلب مجموعة من students ويحتاج أيضًا عادةً أو دائمًا إلى بيانات من users, ، خاصة subscription_type.من الواضح أن نموذج الكائن تم تطبيعه كما ينبغي أن يكون، ولكن هذا لا يعني أن الموارد يجب أن تكون كذلك، أو يجب أن تكون كذلك دائمًا.

هناك بضعة أنماط مختلفة استخدمتها لجعل سيناريوهات مماثلة أكثر كفاءة.ويعتمد أي منهما (إن وجد) على كيفية استهلاك العملاء للموارد.

الموارد المركبة

هذا هو مزيج من كل كائنات المجال أو جزء منها أو أكثر (على سبيل المثال. student و user) في مورد واحد.

منذ ذلك الحين students ويفترض أيضا users, ، يمكنك تضمين كل أو جزء من بيانات المستخدم في مورد الطالب حسب الاقتضاء.

GET /students

{
  address: null
  class_id: 184
  class_name: "I B"
  date_of_birth: null
  first_name: "first"
  gender: null
  grade: 1
  id: 192
  last_name: "last"
  nationality: null
  place_of_birth: null
  ranking_by_class: 0
  ranking_by_school: 0
  registration_number: null
  user_id: 238
  subscription_type: "foo"
}

موارد ذات الصلة

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

GET /students

{
  address: null
  class_id: 184
  class_name: "I B"
  date_of_birth: null
  first_name: "first"
  gender: null
  grade: 1
  id: 192
  last_name: "last"
  nationality: null
  place_of_birth: null
  ranking_by_class: 0
  ranking_by_school: 0
  registration_number: null
  user_id: 238
}

GET /students?include_user=true

{
  address: null
  class_id: 184
  class_name: "I B"
  date_of_birth: null
  first_name: "first"
  gender: null
  grade: 1
  id: 192
  last_name: "last"
  nationality: null
  place_of_birth: null
  ranking_by_class: 0
  ranking_by_school: 0
  registration_number: null
  user_id: 238
  user:
  {
   id: 238
   subscription_type: "foo"
   ...
  }
}

نصائح أخرى

لديك مشكلتان هنا ، لا ينبغي ربطهما معًا - إحداها هي البيانات التي يتم إرجاعها لكل مستخدم لمكالمة الفهرس (/الطلاب) ، والآخر هو عملية التفويض التي يجب أن تحدد البيانات التي يمكن للمستخدم التعرض لها .

فيما يتعلق بمسألة البيانات - لا أعتقد أن هناك قاعدة محددة يجب اتباعها.يعتمد الأمر كليًا على متطلبات تطبيقك.إذا كان حقل نوع_الاشتراك غير ضروري عادةً، فقد تفكر في تمرير معلمة استعلام ('include_extra_data=1' على سبيل المثال) للإشارة إلى أنك بحاجة إليه في طلب محدد، حيث لن يتم إرجاعه افتراضيًا.

فيما يتعلق بمسألة التفويض - يجب أن يتم فصل هذا تمامًا عن البيانات التي تطلبها بناءً على طلبك.يجب أن يكون الخادم قادرًا على تحديد البيانات المرئية للمستخدم وفقًا لمعرف المستخدم.(يمكنك الاطلاع على جوهرة كانكان[1] كحل ممكن).

لذلك، من خلال الجمع بين المسألتين، يجب أن يكون أي نوع من المستخدمين قادرًا على تقديم طلب "/students" مع أو بدون علامة "include_extra_data".إذا وجد الخادم أن المستخدم غير مصرح له برؤية البيانات الإضافية، فيمكنك اختيار أحد خيارين - إما إرجاع البيانات المسموح للمستخدم برؤيتها فقط، أو إرجاع استجابة "401 غير مصرح به".

كلا الطريقتين صالحتان، وتؤثران على الطريقة التي تتعامل بها مع الاستجابة في تطبيق العميل الخاص بك.(أنا شخصياً أفضّل الخيار الأخير، لأنه أكثر وصفًا للعميل).

أتمنى أن يساعدك هذا :)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top