أفضل ممارسات تصميم واجهات برمجة التطبيقات في Laravel

سرقت من هنا.

تحتوي هذه المشاركة على إصدار صوتي بفضل تطبيق Blogcast من ميغيل بيدرافيتا.

أنا لست فقط مهندس DevOps ، لكنني بدأت أيضًا من الصفر من الصفر مع PHP منذ صغري ، في الأيام التي كنت فيها في الصف الخامس. منذ ذلك الحين ، قمت باستمرار بتحسين الكود الخاص بي واكتشفت أن الأشخاص قد تبنوا نوعًا من المعايير الخاصة بالشفرة الأنظف وتصورًا أفضل وبما أنهم معايير ، يمكن للجميع أن يفهموا بشكل أفضل ما كتبه كل مطور آخر في نفس قاعدة البيانات.

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

أساسًا ، API هي واجهة تقوم بإرجاع البيانات بتنسيق خاص يمكن لأي نوع من التطبيقات ، سواء كان تطبيق Android أو تطبيق ويب ، أن يفهمها.

يستخدم JSON على نطاق واسع ، لأنه في كل مكان تقريبًا. الخيار الآخر هو استخدام XML ، لكنني واجهت مشكلة مع بعض واجهات برمجة التطبيقات الخاصة بالجهات الخارجية (وخاصة مزودي الدفع في بلدي) الذين استخدموا XML عبر JSON وكان التطوير حماقة تامة. أوصي بتطوير واجهات برمجة تطبيقات JSON ، طوال الوقت ، ما لم يطلب شخص ما واجهة برمجة تطبيقات XML.

عند تطوير واجهة برمجة تطبيقات ، يجب أن تأخذ بعض الأشياء في الاعتبار ، بهذا الترتيب المحدد:

  • الأمان - يعد تأمينها باستخدام OAuth أو مفتاح API أو CORS أمرًا ضروريًا. اختياريًا ، يجب أن تستخدم أداة التحكم في الاختصار لتقييد الطلبات على تطبيقك.
  • رؤوس - تأكد من أن تطبيقاتك ترسل نوع المحتوى المناسب. رأس نوع المحتوى هو بعض المعلومات التي تخبر العميل الذي يتلقى البيانات: "هذا الشيء الذي أرسله إليك هو JSON" أو "أنه هنا XML. تحليلها بشكل صحيح "، لذلك يعرف المتصفح أو عميلك كيفية فك تشفيره بشكل صحيح.
  • معايير الترميز والتسمية - وهذا هو الخلفية بحتة. تأكد من أنك ثابت في ردودك. التزم بنوع واحد فقط من التسمية والتنسيق المناسب.

أحب برمجة واجهات برمجة التطبيقات (APIs) في Laravel لأنك ترغب في التوسع أكثر مع Event Broadcasting أو ميزات Lumen المفقودة الأخرى التي تجعله سريعًا للغاية ، يمكنك القيام بذلك دون إعادة كتابة المشروع بالكامل من البداية. في حال بقيت على الأقل ، لا تتردد في استخدام Lumen.

الأمان

أكبر مشكلة يجب الاهتمام بها هي الأمن. من السهل تأمينها ، ولكن إذا لم تفعل ذلك بشكل صحيح ، فقد تحصل على وصول غير مرغوب فيه. في Laravel ، قد ترغب في استخدام Laravel Passport - إنه ينتمي إلى النظام البيئي Laravel ، ويدعم المصادقة من خلال معرف التطبيق - App Secret thingy من أجل الحصول على رمز مميز للوصول ، إما لانتحال شخصية شخص ما أو خادم ، إما في الواجهة الخلفية أو الواجهة الأمامية. بشكل أساسي ، ستقدم طلبًا من خلال معرف التطبيق وسرية التطبيق إلى نقطة نهاية OAuth لتلقي رمز مميز ، والذي يمكن إنشاؤه إما عن طريق خادم (أي الوصول إلى API من أمر يتم تشغيله في cronjob كل يوم) أو عن طريق المستخدم الذي قام بتسجيل الدخول إلى التطبيق الخاص بك.

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

رؤوس

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

يبدو الأمر كما لو كانت والدتك تخبرك: "اذهب وشراء بعض الحليب من المتجر ولكن اشترِ فقط من الحليب الذي يحمل علامة X". أنت تعرف ماذا تفعل ، ولكن عليك أن تختار نوعًا واحدًا فقط من الحليب. هو نفس الطلبات: "أريد الحصول على قائمة المستخدمين ، ولكن منحتني في JSON" أو "أريد الحصول على جميع المستخدمين ، ولكن أرسل لي قطعًا من 20" (في حالة تحديد معلمة GET ). لهذا ، يوجد رأس يسمى Accepts ، والذي يمكن أن يكون التطبيق / json في حالة الرغبة في الرد كـ JSON. إنها ليست ضرورة ، ولكن بالنسبة لبعض التطبيقات مثل AJAX ، إذا اكتشفت ذلك العنوان ، فستقوم تلقائيًا بفك تشفير الاستجابة للعميل ، دون الحاجة إلى القيام بشيء مثل هذا:

var data = JSON.parse (response.data)؛

العنوان الآخر الذي يجب أن تكون على دراية به هو Content-Type ، وهو أمر مربك بعض الشيء ، لكنه عكس Accepts: إنه يخبر الخادم كيف يتعامل مع المحتوى الذي يحصل عليه. على سبيل المثال ، إذا كنت ترغب في إرسال بيانات RAW ، مثل سلسلة JSON ، يمكنك تعيين Content-Type على التطبيق / json ، ولكن إذا كنت ترغب في تلقي المحتوى من خلال متغير $ _POST ، فيجب عليك تعيينه على x-www شكل urlencoded. سيساعدك هذا ليس فقط في تحليل المحتوى مباشرةً من خلال $ _POST ، ولكن يجب استخدامه في نماذج HTML لأنه يسهل الوصول إليه. إذا قمت بإرسال بيانات مثل ثنائي ، من خلال مدخلات الملفات ، على سبيل المثال ، تأكد من إرسال بيانات متعددة الأجزاء / المحتوى.

في Laravel ، لن تكون هذه مشكلة نظرًا لأنه يمكنك الوصول إلى البيانات مباشرةً.

للتطبيق / json:

مؤشر الوظيفة (طلب $ الطلب)
{
   $ var = $ request-> متغير ؛
}

ومع ذلك ، في التطبيق / json ، لا يمكنك رؤية استخدام -> all () طريقة محتوى JSON:

مؤشر الوظيفة (طلب $ الطلب)
{
   $ data = $ request-> all ()؛ / / هذا صفيف فارغ ، حتى لدينا بيانات.
}

إذا تم تعيينها على x-www-form-urlencoded أو multipart / form-data ، يمكنك رؤية جميع المتغيرات باستخدام -> all ().

عند الرد ، في Laravel ، يمكنك استخدام استجابة JSON المدمجة أو يمكنك حلها بشكل أفضل واستخدام حزمة مثل Laravel Fractal أو Laravel Responder. من تجربتي الخاصة ، قام Laravel Responder بالمهمة بشكل أفضل ، بطريقة أكثر دلالة. دعني اريك:

getUsers وظيفة (طلب $ الطلب)
{
   عودة الرد () -> النجاح (User :: all ()) -> response ()؛
}

سيؤدي ذلك إلى إرجاع جميع المستخدمين بحالة "موافق 200" وتنسيقها كـ JSON. رائع ، أليس كذلك؟ للأخطاء ، يجب عليك القيام بشيء من هذا القبيل ، والذي يسمح لك بإرسال رمز ورسالة:

getUsers وظيفة (طلب $ الطلب)
{
   $ users = User :: all ()؛

   إذا كان ($ users-> count () === 0) {
      إرجاع Responder () -> خطأ ('no_users' ، 'لا يوجد مستخدمون.') -> response ()؛
   }
   الرد المستجيب () -> النجاح (المستخدمين $) -> الرد () ؛
}

تدعم هذه الحزمة أكثر من ذلك بكثير ، لذا توجه إلى المستندات لأنه يمكن دمجها بسهولة مع المحولات والبيانات المخصصة المرسلة.

معايير الترميز

ما أحب رؤيته هو أن الناس يلتزمون ببعض المعايير التي تناسبهم ، أو أن يكونوا نظيفين. فيما يلي بعض النصائح التي قد تساعدك في إنشاء تعليمات برمجية أنظف وتنظيم طرق واجهة برمجة التطبيقات بشكل أفضل.

استخدم ملف route / api.php لطرق API

يأتي Laravel مع مسارات منفصلة / api.phpfile التي تتأخر عن ملف route / web.php المعتاد المستخدم في توجيه الويب. يتم إنشاء ملف api.php لتخزين طرق API الخاصة بك. يحتوي على برنامج وسيط مطبق داخليًا (يمكن رؤيته في التطبيق / Http / Kernel.php ، في المتغير $ middlewareGroups ، ضمن api) وبادئة / api ، بحيث تكون جميع المسارات المحددة متاحة بالفعل لـ / api

الاستفادة من أسماء الطريق

ما أود القيام به ، هو تعيين إعداد لواجهة برمجة التطبيقات (API) بأكملها ، بحيث يمكنني الوصول إلى المسارات باسمهم باستخدام api. اختصار.

Route :: get ('/ users'، 'API \ UserController @ getUsers') -> name ('get.users')؛

يمكن استخدام عنوان URL لهذا المسار ("get.users") ، لكنه قد يتعارض مع web.php.

المسار :: group (['as' => 'api.'] ، function () {
   Route :: get ('/ users'، 'API \ UserController @ getUsers') -> name ('get.users')؛
})؛

بهذه الطريقة ، سيكون لديك على الطريق ('api.get.users').

إذا كنت تستخدم أسماء المسارات ، إذا كانت اختبارات الكتابة الخاصة بك ، فلن تحتاج إلى استبدال عنوان URL في كل مكان إذا كنت تخطط لتغيير موقع URL والحفاظ على اسم المسار.

طرق وصفية ، لكنها بسيطة

من الممارسات الجيدة تجميع المسارات في أقسام ، مثل المستخدمين والمنشورات وما إلى ذلك واستخدام أبسط الأشياء التي يمكنك التفكير بها:

المسار :: group (['as' => 'api.'] ، function () {
   المسار :: group (['as' => 'account.'، 'prefix' => '/ account']، function () {
         Route :: get ('/ users'، 'API \ UserController @ getUsers') -> name ('get.users')؛
         Route :: get ('/ user / {id}'، 'API \ UserController @ getUser') -> name ('get.user')؛
         Route :: post ('/ user'، 'API \ UserController @ createUser') -> name ('create.user')؛
         // الخ
   })؛
})؛

استخدم :: get () للحصول على البيانات ، :: post () لإنشاء ، :: patch () أو :: put () للتحرير و :: delete () لحذف البيانات. مثل هذا ، ينتهي بك المطاف باستخدام نفس نقطة النهاية ، ولكن مع اختلاف أنواع الطلبات ، ستتمكن من إطلاق إجراءات أخرى.

داخل وحدة التحكم الخاصة بك ، يجب أن تستخدم ترميزًا بسيطًا وأن تستفيد من فصول الطلب ، كما شرحت في "دفع لارافيل" بشكل أكبر - أفضل النصائح والممارسات الجيدة لـ Laravel 5.7

getUsers وظيفة (طلب $ الطلب)
{
   $ users = User :: all ()؛
   الرد المستجيب () -> النجاح (المستخدمين $) -> الرد () ؛
}
وظيفة getUser (معرف $ ، طلب $ طلب)
{
   $ user = User :: findOrFail ($ id)؛
   الرد المستجيب () -> النجاح (المستخدم $) -> الرد () ؛
}
وظيفة createUser (طلب CreateUserRequest $)
{
    $ user = User :: create ($ request-> all ())؛
    الرد المستجيب () -> النجاح (المستخدم $) -> الرد () ؛
}
// الخ

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

من الصعب جدا أن نفهم؟ اوصل لي!

إذا كان لديك المزيد من الأسئلة حول Laravel ، إذا كنت بحاجة إلى مساعدة بشأن أي معلومات متعلقة بـ DevOps أو تريد ببساطة أن تقول شكراً لك ، يمكنك أن تجدني على Twitterrennokki!

انضم إلى مجتمعنا Slack وقراءة موضوعات Faun الأسبوعية الخاصة بنا ⬇

إذا كانت هذه المشاركة مفيدة ، فالرجاء النقر على زر التصفيق أدناه عدة مرات لإظهار دعمك للمؤلف! ⬇