Rails/api app

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث

استعمال ريلز في التطبيقات التي تعتمد على الواجهة البرمجية فقط

في هذا الدليل ستتعلم:

  • ما تقدمه ريلز للتطبيقات ذات الواجهة البرمجية فقط.
  • كيفية ضبط ريلز للبدء دون أي ميزات للمتصفح.
  • كيفية تحديد البرامج الوسيطة (middleware) التي تريد تضمينها.
  • كيفية تحديد الوحدات لاستخدامها في وحدة التحكم الخاصة بك.

ما الذي يعنيه «تطبيق ذو واجهة برمجية فقط»؟

تقليديًا، عندما قال الناس أنهم استخدموا ريلز كـ "واجهة برمجية"، فقد كان يعني توفير واجهة برمجية يمكن الوصول إليها برمجيًا جنبًا إلى جنب مع تطبيق الويب الخاص بهم. على سبيل المثال، يوفر GitHub واجهة برمجية يمكنك استخدامها من العملاء المخصصين.

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

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

بدلًا من استخدام ريلز لإنشاء لغة HTML تتواصل مع الخادم من خلال النماذج والروابط، يعالج العديد من المطورين تطبيقات الويب الخاصة بهم على أنها مجرد عميل واجهة برمجة تطبيقات تُسلَّم بتنسيق HTML مع JavaScript ويستهلك واجهة برمجة تطبيقات JSON.

يغطي هذا الدليل بناء تطبيق ريلز يخدم موارد JSON إلى عميل واجهة برمجة التطبيقات، بما في ذلك أطر عمل العميل.

لماذا تستخدم ريلز لواجهة برمجة تطبيقات JSON؟

السؤال الأول الذي يفكر فيه الكثير من الأشخاص عند التفكير في إنشاء واجهة برمجة تطبيقات JSON باستخدام ريلز هو: "أليس استخدام ريلز لاستخراج بعض البيانات المكتوبة بصيغة JSON أمر مبالغ فيه بشدة؟ ألا يجب فقط أن أستخدم شيئًا مثل Sinatra؟".

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

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

لنلقِ نظرة على بعض الأشياء غير التقليدية التي توفرها ريلز والتي لا تزال سارية على تطبيقات واجهة برمجة التطبيقات.

التعامل عند طبقة البرمجيات الوسيطة (middleware layer):

  • إعادة التحميل: تدعم تطبيقات ريلز إعادة التحميل الشفاف (transparent reloading). هذا يعمل حتى إذا أصبح التطبيق الخاص بك كبيرًا، وإعادة تشغيل الخادم لكل طلب تصبح عملية غير قابل للتطبيق.
  • وضع التطوير: تأتي تطبيقات ريلز مع الافتراضات الذكية للتطوير، مما يجعل التطوير مسليًا دون المساس بأداء وقت الإنتاج.
  • وضع الاختبار: يشبه وضع التطوير.
  • التسجيل: تسجل تطبيقات ريلز كل طلب، مع مستوى من التفصيل والإسهاب المناسب للوضع الحالي. تتضمن سجلات ريلز قيد التطوير معلومات حول بيئة الطلب واستعلامات قاعدة البيانات ومعلومات الأداء الأساسية.
  • الأمن: يكتشف ريلز هجمات انتحال IP ويعطلها ويتعامل مع توقيعات التشفير بطريقة حذرة من حدوث هجوم التوقيت. لا تعرف ما هو هجوم انتحال IP أو هجوم التوقيت؟ حسنًا، ألق نظرة على الروابط.
  • تحليل المعامل: هل تريد تحديد المعاملات على أنها JSON بدلًا من أنها سلسلة مشفرة لعناوين URL؟ ليس هناك أى مشكلة. ستعمل ريلز على فك شيفرة JSON وجعلها متوفرة في params. هل ترغب في استخدام المعاملات المتداخلة لعناوين URL المتداخلة؟ هذا يعمل أيضًا.
  • طلبات GET المشروطة: يعالج ريلز طلبات GET المشروطة (ETag و Last-Modified)، وتعالج ترويسات الطلب، وتعيد ترويسات الرد المناسب ورمز الحالة. كل ما عليك القيام به هو استخدام ?stale الذي يتحقق من وحدة التحكم، وسيتولى ريلز جميع تفاصيل HTTP نيابة عنك.
  • طلبات HEAD: ستحول ريلز طلبات HEAD إلى GET، وتعيد الترويسات فقط إلى المخرج. هذا يجعل HEAD يعمل بشكل موثوق في جميع واجهات برمجة التطبيقات ريلز.

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

التعامل عند طبقة الإجراء Pack:

  • توجيه الموارد: إذا كنت تنشئ واجهة برمجة تطبيقات JSON RESTful (أي RESTful JSON API)، فستحتاج إلى استخدام جهاز توجيه ريلز. تعني التعيينات النظيفة والتقليدية من HTTP إلى وحدات التحكم عدم الحاجة إلى قضاء بعض الوقت في التفكير في كيفية تصميم واجهة برمجة التطبيقات الخاصة بك من حيث طلبات HTTP.
  • إنشاء عنوان URL: الجانب الآخر للتوجيه هو إنشاء عنوان URL. تتضمن واجهة برمجة التطبيقات الجيدة المستندة إلى HTTP عناوين URL (راجع واجهة برمجة تطبيقات GitHub Gist على سبيل المثال).
  • ردود الترويسة وإعادة التوجيه: إن head، :no_content و redirect_to و user_url(current_user)‎ تأتي في متناول اليدين. بالتأكيد، يمكنك إضافة ترويسات للرد يدويًا، ولكن لماذا؟
  • التخزين المؤقت: يوفر ريلز آلية تخزين الصفحة، وتخزين الإجراء، وتخزين الجزئيات. يكون التخزين المؤقت للشيفرة مفيدًا بشكل خاص عند إنشاء كائن JSON متداخل.
  • الاستيثاق الأساسي (Basic Authentication)والاستيثاق عبر قيم مشفرة مختصرة (Digest Authentication) والاستيثاق عبر الرموز (Token Authentication): تأتي ريلز مع دعم متميز لثلاثة أنواع من استيثاق HTTP المشار إليها.
  • أدوات قياس: يحتوي ريلز على واجهة برمجة تطبيقات لأدوات قياس (instrumentation API) تعمل على استدعاء معالجات مسجلة لمجموعة متنوعة من الأحداث مثل معالجة الإجراءات، وإرسال ملف أو بيانات، وإعادة توجيه، و استعلامات قاعدة البيانات. تأتي حمولة كل حدث مع المعلومات ذات الصلة (لحدث معالجة الإجراءات، تتضمن الحمولة وحدة التحكم، والإجراء، والمعاملات، وتنسيق الطلب، وطريقة الطلب والمسار الكامل للطلب).
  • المولدات: غالبا ما تكون مفيدة لتوليد مورد والحصول على النموذج الخاص بك، ووحدة التحكم، وحزم اختبار، والمسارات التي أُنشئت لك في أمر واحد لمزيد من التغيير والتبديل. تشبه التهجيرات وغيرها.
  • الإضافات: تأتي العديد من مكتبات التي توفرها جهة ثالثة مع دعم ريلز الذي يقلل أو يقضي على تكلفة إعداد ولصق المكتبة وإطار الويب. يتضمن ذلك أشياءً مثل إلغاء المولدات الافتراضية وإضافة مهام Rake واحترام اختيارات ريلز (مثل التسجيل وذاكرة التخزين المؤقت الخلفي).

وبطبيعة الحال، فإن عملية إقلاع ريلز تجمع جميع المكونات المسجلة. على سبيل المثال، عملية إقلاع ريلز هي العملية التي تستخدم الملف config/database.yml الخاص بك عند ضبط السجل الفعال.

الإصدار المختصر: قد لا تكون قد فكرت في أي أجزاءٍ من ريلز لا تزال قابلة للتطبيق حتى إذا قمت بإزالة طبقة الواجهة، ولكن الإجابة تبين أنها أكثر من ذلك.

الضبط الأساسي

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

إنشاء تطبيق جديد

يمكنك إنشاء تطبيق api ريلز جديد:

$ ريلز new my_api --api

هذا سيفعل ثلاثة أمور أساسية بالنسبة لك:

  • قم بتكوين التطبيق الخاص بك لتبدأ بمجموعة محدودة من البرامج الوسيطة أكثر من المعتاد. وبالتحديد، لن تتضمن أي برامج وسيطة مفيدة بشكل أساسي لتطبيقات المستعرض (مثل دعم ملفات تعريف الارتباط) بشكل افتراضي.
  • جعل ApplicationController ترث من ActionController :: API بدلاً من ActionController :: Base. كما هو الحال مع البرامج الوسيطة ، سيؤدي هذا إلى إهمال أي وحدات تحكم في الإجراء تعمل على توفير وظائف تستخدم بشكل رئيسي من قبل تطبيقات المستعرض.
  • قم بتكوين المولدات لتخطي إنشاء الواجهات والمساعدات والممتلكات عند إنشاء مورد جديد.

تغيير تطبيق موجود

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

في config / application.rb أضف السطر التالي في أعلى تعريف فئة التطبيق:

config.api_only = true

في config / environments / development.rb، اضبط config.debug_exception_response_format لتهيئة التنسيق المستخدم في الإستجابة عند حدوث أخطاء في وضع التطوير.

لعرض صفحة HTML تحتوي على معلومات تصحيح الأخطاء، استخدم القيمة :default.

config.debug_exception_response_format = :default

لتقديم معلومات التصحيح التي تحتفظ بتنسيق الاستجابة، استخدم القيمة :api.

config.debug_exception_response_format = :api

بشكل افتراضي، يتعين config.debug_exception_response_format على :api، عند تعيين config.api_only على true.

أخيرًا، داخل app/controllers/application_controller.rb، بدلاً من:

class ApplicationController < ActionController::Base

End

افعل:

class ApplicationController < ActionController::API

End

اختيار البرامج الوسيطة

يأتي تطبيق API مع الوسيطة التالية افتراضيًا:

  • Rack::Sendfile
  • ActionDispatch::Static
  • ActionDispatch::Executor
  • ActiveSupport::Cache::Strategy::LocalCache::Middleware
  • Rack::Runtime
  • ActionDispatch::RequestId
  • ActionDispatch::RemoteIp
  • ريلز::Rack::Logger
  • ActionDispatch::ShowExceptions
  • ActionDispatch::DebugExceptions
  • ActionDispatch::Reloader
  • ActionDispatch::Callbacks
  • ActiveRecord::Migration::CheckPending
  • Rack::Head
  • Rack::ConditionalGet
  • Rack::ETag

انظر قسم البرامج الوسيطة الداخلية من دليل الحامل لمزيد من المعلومات عنهم.

قد تضيف الإضافات الأخرى، بما في ذلك Active Record، برامج وسيطة إضافية. بشكل عام، تكون هذه البرامج الوسيطة ملزمة لنوع التطبيق الذي تبنيه، ولها معنى في تطبيق ريلز  فقط API.

يمكنك الحصول على قائمة بجميع البرامج الوسيطة في تطبيقك عبر:

$ ريلز middleware

استخدام التخزين المؤقت للبرامج الوسيطة

بشكل افتراضي، سيضيف ريلز وسيطًا يوفر مخزنًا مؤقتًا يستند إلى تكوين التطبيق الخاص بك (ذاكرة التخزين المؤقت بشكل افتراضي). هذا يعني أن ذاكرة التخزين المؤقت HTTP المضمنة ستعتمد عليه.

على سبيل المثال، باستخدام التابع stale؟:

def show

 @post = Post.find(params[:id])

 if stale?(last_modified: @post.updated_at)

   render json: @post

 end

End

استدعاء إلى stale؟ و يقارن رأس الصفحة If-Modified-Since في الطلب مع @ post.updated_at. إذا كان رأس الصفحة أحدث من التعديل الأخير، يعرض هذا الإجراء استجابة "304 غير معدلة". بخلاف ذلك، سيعرض الاستجابة و تضمن في رأس الصفحة Last-Modified.

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

def show

 @post = Post.find(params[:id])

 if stale?(last_modified: @post.updated_at, public: true)

   render json: @post

 end

End

وهذا يعني أن ذاكرة وسيطة التخزين المؤقت تخزن القيمة Last-Modified لعنوان URL في ذاكرة التخزين المؤقت ريلز، وإضافة عنوان If-Modified-Since إلى أي طلبات واردة لاحقة لنفس عنوان URL.

فكر في ذلك كتخزين مؤقت للصفحة باستخدام دلالات HTTP.

استخدام Rack::Sendfile

عند استخدام التابع send_file داخل وحدة تحكم ريلز، يعين رأس الصفحة X-Sendfile

Rack :: Sendfile مسؤولة عن إرسال الملف بالفعل.

إذا كان خادم الواجهة الأمامية يدعم إرسال الملفات المتسارعة ، سيلغي Rack :: Sendfile تحميل الملف الفعلي الذي يرسل العمل إلى الخادم الأمامي.

يمكنك تكوين اسم رأس الصفحة التي يستخدمها خادم الواجهة الأمامية لهذا الغرض باستخدام config.action_dispatch.x_sendfile_header في ملف تكوين البيئة المناسبة .

يمكنك معرفة المزيد حول كيفية استخدام Rack :: Sendfile مع front-ends الشائعة في وثائق Rack :: Sendfile.

في ما يلي بعض القيم لرأس الصفحة هذا لبعض الخوادم الشائعة، بمجرد تهيئة هذه الخوادم لدعم إرسال الملفات بسرعة:

# Apache and lighttpd

config.action_dispatch.x_sendfile_header = "X-Sendfile"

# Nginx

config.action_dispatch.x_sendfile_header = "X-Accel-Redirect"

تأكد من إعدادات تكوين الخادم الخاص بك لدعم هذه الخيارات باتباع الإرشادات الموجودة في الوثائق Rack :: Sendfile.

استخدام ActionDispatch::Request

 ActionDispatch::Request#params سوف يأخذ المعاملات من العميل بتنسيق JSON وإتاحتها في وحدة التحكم داخل params.

لاستخدام هذا، سيحتاج العميل إلى تقديم طلب باستخدام معاملات JSON-encoded وتحديد نوع المحتوى كــ application/json.

إليك مثال في jQuery:

jQuery.ajax({

 type: 'POST',

 url: '/people',

 dataType: 'json',

 contentType: 'application/json',

 data: JSON.stringify({ person: { firstName: "Yehuda", lastName: "Katz" } }),

 success: function(json) { }

});

سيشاهد ActionDispatch :: Request نوع المحتوى وستكون المعاملات الخاصة بك:

{ :person => { :firstName => "Yehuda", :lastName => "Katz" } }

البرامج الوسيطة الأخرى

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

  • Rack::MethodOverride.
  • ActionDispatch::Cookies.
  • ActionDispatch::Flash.
  • لإدارة الجلسة:
  • ActionDispatch::Session::CacheStore.
  • ActionDispatch::Session::CookieStore.
  • ActionDispatch::Session::MemCacheStore.

يمكن إضافة أي من هذه البرامج الوسيطة عبر:

config.middleware.use Rack::MethodOverride

إزالة البرامج الوسيطة

إذا كنت لا ترغب في استخدام برامج وسيطة ضُمنت افتراضيًا في مجموعة البرامج الوسيطة لـ API فقط، فيمكنك إزالتها باستخدام:

config.middleware.delete ::Rack::Sendfile

ضع في اعتبارك أن إزالة هذه الوسيطة ستزيل الدعم لميزات معينة في وحدة التحكم بالعمل.

اختيار وحدات التحكم

يأتي تطبيق API (باستخدام ActionController :: API) مع وحدات التحكم التالية بشكل افتراضي:

  • ActionController::UrlFor: يجعل url_for والمساعدين المتشابهين متاحة.
  • ActionController::Redirecting: يقدم الدعم redirect_to.
  • AbstractController::Rendering و ActionController::ApiRendering: الدعم الأساسي للتقديم.
  • ActionController::Renderers::All: يدعم render :json والاصدقاء.
  • ActionController::ConditionalGet: يدعم stale؟.
  • ActionController::BasicImplicitRender: يتأكد من عرض استجابة فارغ، إذا لم يكن هناك استجابة صريحة.
  • ActionController::StrongParameters: دعم المعاملات للقائمة البيضاء بالاشتراك مع تعيين كتلة نموذج نشط.
  • ActionController::ForceSSL: تدعم force_ssl.
  • ActionController::DataStreaming: تدعم send_file و send_data.
  • AbstractController::Callbacks: يدعم before_action و المساعدين المشابهين.
  • ActionController::Rescue: يدعم rescue_from.
  • ActionController::Instrumentation: دعم خطافات الأجهزة المحددة من قبل وحدة التحكم في الإجراء (انظر دليل الأجهزة لمزيد من المعلومات حول هذا الأمر).
  • ActionController::ParamsWrapper: يلف تجزئة المعاملات في التجزئة المتداخلة، بحيث لا تضطر إلى تحديد عناصر الجذر لإرسال طلبات POST على سبيل المثال.
  • ActionController::Head: دعم لإعادة الإستجابة بدون محتوى، فقط رؤوس الصفحات.

قد تضيف الإضافات الأخرى وحدات إضافية. يمكنك الحصول على قائمة بجميع الوحدات المضمّنة في ActionController :: API في وحدة التحكم في ريلز:

$ bin/ريلز c

>> ActionController::API.ancestors - ActionController::Metal.ancestors

=> [ActionController::API,

   ActiveRecord::Railties::ControllerRuntime,

   ActionDispatch::Routing::RouteSet::MountedHelpers,

   ActionController::ParamsWrapper,

   ... ,

   AbstractController::Rendering,

   ActionView::ViewPaths]

إضافة وحدات أخرى

تعرف جميع وحدات "التحكّم في الإجراءات" بالوحدات التابعة لها، لذا يمكنك أن تشعر بإدراج أي وحدات في وحدات التحكم لديك، ويتضمن جميع الاعتمادات وإعدادها أيضًا.

بعض الوحدات الشائعة التي قد ترغب في إضافتها:

  • AbstractController::Translation: دعم l و t توابع الموقع و الترجمة.
  • دعم استيثاق HTTP الأساسية أو digest أو الرمز المميز:
  • ActionController::HttpAuthentication::Basic::ControllerMethods.
  • ActionController::HttpAuthentication::Digest::ControllerMethods,
  • ActionController::HttpAuthentication::Token::ControllerMethods.
  • ActionView::Layouts: دعم للتخطيطات عند التقديم.
  • ActionController::MimeResponds: دعم respond_to.
  • ActionController::Cookies: تدعم cookies، والتي تتضمن دعم ملفات تعريف الارتباط الموقعة والمشفرة. هذا يتطلب ملفات تعريف الارتباط الوسيطة.

أفضل مكان لإضافة وحدة نمطية هو في ApplicationController الخاص بك، ولكن يمكنك أيضًا إضافة وحدات نمطية إلى وحدات التحكم الفردية.

المراجع:

  • استخدام ريلز لتطبيقات API فقط.