تطوير مكون إضافي مخصص لـ APISIX باستخدام Lua و ChatGPT

Bobur Umurzokov

Bobur Umurzokov

June 12, 2023

Technology

إحدى الميزات الرئيسية لـ Apache APISIX هي قابليتها للتوسيع من خلال الإضافات. تسمح APISIX لك ببناء إضافة مخصصة لإضافة وظائف إضافية وإدارة حركة مرور API بشكل أكثر كفاءة. غالبًا ما تستخدم لغة برمجة Lua لتنفيذ إضافات جديدة أو الاستفادة من مشغلات الإضافات لتطوير إضافات بلغة البرمجة المفضلة لديك. ومع ذلك، فإن APISIX تدعم Lua بشكل أفضل. بعد كتابة بعض الإضافات لـ APISIX باستخدام Lua، فهمت أنك لست بحاجة إلى معرفة أساسيات برمجة Lua أو أن تكون خبيرًا في هذه اللغة على الإطلاق عندما يكون صديقك ChatGPT دائمًا معك. على سبيل المثال، مع خلفيتي في Java و C#، يمكنني فهم الكود والمنطق المكتوب بلغة Lua وأعتقد أنك تستطيع فعل الشيء نفسه.

ستوجهك هذه المقالة خلال عملية تطوير إضافة مخصصة جديدة تسمى file-proxy لـ APISIX باستخدام Lua و ChatGPT (نستخدمه لكتابة بعض أكواد Lua لنا). ستُستخدم هذه الإضافة لتعريض الملفات الثابتة عبر API وجلب ملف من عنوان URL محدد.

تم بناء APISIX لتعزيز الوظائف الحالية لـ Nginx، ويوفر Nginx مجموعة من وحدات Lua القابلة لإعادة الاستخدام التي تستفيد منها APISIX.

أهداف التعلم

ستتعلم ما يلي خلال المقالة:

  • كيفية تطوير إضافة file-proxy جديدة.
  • كيفية استخدام ChatGPT بكفاءة لإنشاء أكواد Lua.
  • خطوات بناء إضافتك الخاصة لـ APISIX.

حالة استخدام إضافة file-proxy الجديدة

قبل القفز إلى تنفيذ الإضافة الفعلي، دعنا نفهم أولاً سبب حاجتنا لهذه الإضافة. في وقت كتابة هذا المنشور، قد لا توفر APISIX إضافة مدمجة لحالة مشابهة. لهذا السبب سنقوم ببناء إضافة جديدة. غالبًا ما نريد تعريض ملف ثابت (Yaml، JSON، JavaScript، CSS، أو ملفات صور) عبر API.

على سبيل المثال، تعمل بوابة API APISIX كبوابة أمامية في تطبيقك لتوجيه الطلبات الواردة إلى نقاط نهاية API متعددة، وهي المكان المناسب لتحديد جميع عناوين URL للخوادم، المسارات، المعلمات، أوصاف كل نقطة نهاية API ومدخلاتها ومخرجاتها. وتقوم ببناء مواصفات OpenAPI لتوثيق API. ملف OpenAPI .yaml يشبه خريطة توجه مستخدم API لفهم التفاعل مع API الخاص بك. من خلال توفير مسار ملف openapi.yaml (حيث يتم تخزينه في خادمك) للإضافة، يمكنك جلب الملف وعرضه مباشرة عبر بوابة API الخاصة بك، مما يوفر واجهة متسقة لمستهلكي API. ثم يمكن لمستخدمي API الوصول إلى ملف .yaml عبر العنوان URL المحدد (https://example.com/openapi.yaml).

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

خطوات تطوير إضافة file-proxy

سنقوم بتشغيل APISIX محليًا وستكون بوابة API الخاصة بنا مستضافة على http://localhost:9080. عندما يكون التطوير جاهزًا، يمكنك نشره على خادمك أو أي مزود سحابي. بشكل أساسي، نريد وضع ملف openapi.yaml في المسار http://localhost:9080/openapi.yaml. ستتعلم كيفية تحقيق ذلك.

المتطلبات الأساسية

  • قبل البدء، من الجيد أن يكون لديك فهم أساسي لـ APISIX. الإلمام ببوابة API، ومفاهيمها الرئيسية مثل المسارات، الخوادم العلوية، واجهة برمجة التطبيقات الإدارية، الإضافات. كما أن الفهم الأساسي لبروتوكول HTTP مفيد أيضًا.
  • يتم استخدام Docker لتثبيت etcd و APISIX في حاويات.
  • يتم استخدام curl لإرسال الطلبات إلى واجهة برمجة التطبيقات الإدارية لـ APISIX. يمكنك أيضًا استخدام أدوات مثل Postman للتفاعل مع API.

فهم مشروع العرض والملفات

سنستفيد من مشروع file-proxy demo الحالي على GitHub. له هيكل مشابه جدًا لمشروع Apisix docker example الحالي، فقط قمنا بإزالة الملفات غير الضرورية لجعل العرض بسيطًا. يحتوي المشروع على 3 مجلدات، docker-compose.yml، وملفات openapi.yaml النموذجية.

  • يحدد docker-compose.yml حاويتين واحدة لـ APISIX والأخرى لـ etcd (وهو تخزين التكوين لـ APISIX).
  • يحتوي مجلد custom-plugins على تنفيذ إضافة file-proxy بلغة Lua. سنراجعه في الأقسام التالية.
  • openapi.yaml هو مجرد نموذج لمواصفات OpenAPI التي نعرضها.

تنفيذ إضافة file-proxy

نبدأ بطلب مساعدة ChatGPT حول كيفية تنفيذ إضافة file-proxy مخصصة لـ APISIX باستخدام Lua. يولد ChatGPT دليلًا مشابهًا تقريبًا للتنفيذ الفعلي، ولكن الإجابة مجردة جدًا وعندما تتبع العملية، ستنتهي بإضافة غير عاملة. ومع ذلك، يساعدنا في استخراج أكواد Lua مفيدة. إذا كنا نعرف العملية الحقيقية لتطوير الإضافات، سيكون من الأسهل الجمع بين المعرفة في الممارسة.

تنفيذ إضافة file-proxy باستخدام ChatGPT

1. إنشاء ملف Lua

نقوم بإنشاء ملف Lua جديد فارغ في مجلد /custom-plugins للمشروع. يجب أن يكون اسم الملف هو اسم الإضافة الخاصة بنا. على سبيل المثال، إذا كانت الإضافة الخاصة بك تسمى file-proxy، يجب إنشاء ملف باسم file-proxy.lua.

2. تسجيل الإضافة في APISIX

يحتاج APISIX إلى معرفة مكان وجود ملف الإضافة هذا وقادر على تشغيل الإضافة وفقًا لذلك. للقيام بذلك، يجب أولاً تحديد مسار الملف حيث يجد APISIX ملف file-proxy.lua عن طريق إضافة مسار الملف إلى السمة extra_lua_path لـ APISIX في ملف config.yaml.

apisix:
  extra_lua_path: "/opt/?.lua"
  node_listen: 9080

الآن قد تسأل لماذا تم تعيين مسار الملف إلى /opt/?.lua. لأننا نقوم بتشغيل APISIX باستخدام docker. قد تلاحظ ذلك في ملف docker-compose.yml هناك 3 مجلدات ./custom-plugins:/opt/apisix/plugins:ro

volumes:
      - ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
      - ./openapi.yaml:/usr/local/apisix/conf/openapi.yaml:ro
      - ./custom-plugins:/opt/apisix/plugins:ro

يقوم هذا بتركيب المجلد المحلي ./custom-plugins حيث يوجد ملف file-proxy.lua مع تنفيذ الإضافة المخصصة كحجم قراءة فقط في حاوية docker في المسار /opt/apisix/plugins. يسمح هذا بإضافة الإضافة المخصصة إلى APISIX في وقت التشغيل إلى مسار آخر في Docker وهو داخل /opt/?.lua. وبالمثل، قمنا بنسخ الملفين الآخرين إلى مجلدات Docker.

الخطوة التالية، نقوم بتمكين الإضافة في قائمة إضافات APISIX. يتم ذلك عن طريق إضافة اسم الإضافة إلى قائمة plugins في ملف تكوين APISIX (config.yaml):

plugins:
  - file-proxy

لاحظ أن هذا الإجراء سيتجاوز جميع الإضافات الافتراضية المحددة في config-default.yaml. تحتاج إلى إضافة الإضافات الأخرى يدويًا باسمها إذا كنت تريد استخدام إضافتك المخصصة معها.

3. تفصيل كود Lua لإضافة file-proxy

حتى الآن، قمنا فقط بتسجيل الإضافة التي لا تفعل شيئًا. حان الوقت لتنفيذها. يتم تنفيذ منطق الإضافة كوظائف Lua. يمكنك التحقق من كيفية القيام بذلك في ملف file-proxy.lua.

دعنا نفصل ملف file-proxy.lua لفهم هيكل الكود والتدفق بشكل أفضل مما يساعدك على إنشاء إضافات جديدة بنفسك. يمكنك ببساطة أن تطلب من ChatGPT شرح كود Lua:

شرح كود Lua باستخدام ChatGPT

في الواقع، حصلنا على شرح جيد للكود (لأنه كان مكتوبًا جزئيًا بواسطة ChatGPT).

وصف الصورة

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

4. هيكل ملف الإضافة

يجب أن يحتوي كل ملف Lua للإضافة على الهيكل التالي:

1. الوحدات: نقوم باستيراد الوحدات/المكتبات اللازمة للإضافة

local core = require("apisix.core")
...

2. اسم الإضافة: كل إضافة لها اسم فريد، يمكن أن يكون نفس اسم ملف Lua الخاص بنا.

local plugin_name = "file-proxy"

3. مخطط الإضافة: كل إضافة لها مخطط إضافة، حيث نحدد عادةً المدخلات للإضافة. المدخلات التي سنمررها من تكوين مسار APISIX، والتي ستشاهدها لاحقًا عند اختبار الإضافة. بالنسبة لإضافة file-proxy، تحتاج الإضافة إلى مسار ملف لقراءة الملف وإرجاع استجابة لذا فإن المعلمة هي path وهي من نوع سلسلة. يمكنك فهم المخطط مثل إعلان طريقة مع معلمات في لغات البرمجة الأخرى.

local plugin_schema = {
    type = "object",
    properties = {
        path = {
            type = "string" -- مسار الملف الذي سيتم تقديمه
        },
    },
    required = {"path"} -- المسار مطلوب
}

4. تعريف الإضافة: إنه جزء مهم جدًا من تنفيذ الإضافة الذي نحدده كجدول بخصائص version، priority، name، و schema. name و schema هما اسم الإضافة والمخطط المحددين مسبقًا. يتم استخدام version و priority بواسطة APISIX لإدارة الإضافة. يشير الإصدار عادةً إلى الإصدار الحالي المستخدم مثل إصدار API. إذا قمت بنشر وتحديث منطق إضافتك، سيكون 1.1 (يمكنك تعيين أي إصدار تريده). ولكن يجب أن تكون حذرًا جدًا في اختيار الأولوية. تحدد الحقل priority الترتيب والمرحلة التي يجب تنفيذ إضافتك فيها. على سبيل المثال، سيتم تنفيذ إضافة 'ip-restriction' ذات الأولوية 3000 قبل إضافة 'example-plugin' ذات الأولوية 0. هذا بسبب قيمة الأولوية الأعلى لإضافة 'ip-restriction'. إذا كنت تقوم بتطوير إضافتك الخاصة، تأكد من أنك اتبعت ترتيب الإضافات حتى لا تخلط ترتيب الإضافات الحالية. يمكنك التحقق من ترتيب الإضافات الحالية في ملف config-default.yaml وفتح دليل تطوير إضافات Apache APISIX لتحديد ذلك.

local _M = {
    version = 1.0,
    priority = 1000,
    name = plugin_name,
    schema = plugin_schema
}

5. فحص المخطط: تُستخدم وظيفة check_schema Lua للتحقق من صحة الإضافة في تكوين المسار (ستراه قريبًا في قسم الاختبار) مقابل مخطط الإضافة الذي حددناه مسبقًا.

-- وظيفة للتحقق من صحة تكوين الإضافة
function _M.check_schema(conf)
  -- التحقق من التكوين مقابل المخطط
  local ok, err = core.schema.check(plugin_schema, conf)
  -- إذا فشل التحقق، إرجاع false والخطأ
  if not ok then
      return false, err
  end
  -- إذا نجح التحقق، إرجاع true
  return true
end

6. منطق الإضافة: access هي الوظيفة الأساسية حيث يمكننا كتابة المنطق الرئيسي للإضافة. يتم استدعاؤها خلال مرحلة الوصول في خط معالجة طلبات Nginx ويمكننا التحكم في حركة المرور وكتابة تعليمات مخصصة. بالنسبة لـ file-proxy، نحتاج إلى فتح الملف المحدد في تكوين الإضافة، قراءة محتواه، وإرجاع المحتوى كاستجابة. إذا تعذر فتح الملف، يتم تسجيل خطأ وإرجاع حالة 404 Not Found. إنه المكان المحدد الذي نعطي فيه هذا العمل لـ ChatGPT:

كود Lua لإضافة file-proxy باستخدام ChatGPT

بعد أن قمنا ببناء الكود وإعادة هيكلته، يبدو كما يلي:

function _M.access(conf, ctx)
  -- فتح الملف المحدد في التكوين
  local fd = io.open(conf.path, "rb")
  -- إذا تم فتح الملف بنجاح، قراءة محتواه وإرجاعه كاستجابة
  if fd then
    local content = fd:read("*all")
    fd:close()
    ngx.header.content_length = #content
    ngx.say(content)
    ngx.exit(ngx.OK)
  else
    -- إذا تعذر فتح الملف، تسجيل خطأ وإرجاع حالة 404 Not Found
    ngx.exit(ngx.HTTP_NOT_FOUND)
    core.log.error("الملف غير موجود: ", conf.path, ", معلومات الخطأ: ", err)
  end
end

7. منطق التسجيل: من الأفضل دائمًا تسجيل تكوين الإضافة حتى نتمكن من تصحيح الأخطاء والتحقق من عمل الإضافة كما نتوقع. يمكننا تسجيل الطلبات إلى الإضافة والاستجابات.

-- وظيفة يتم استدعاؤها خلال مرحلة التسجيل
function _M.log(conf, ctx)
    -- تسجيل تكوين الإضافة وسياق الطلب
    core.log.warn("التكوين: ", core.json.encode(conf))
    core.log.warn("السياق: ", core.json.encode(ctx, true))
end

تثبيت Apache APISIX

بعد أن تعلمنا كيفية تطوير إضافة file-proxy المخصصة، وتسجيلها في APISIX. حان الوقت لاختبار الإضافة. يمكنك بسهولة تثبيت مشروع apisix-file-proxy-plugin-demo عن طريق تشغيل docker compose up من مجلد جذر المشروع بعد أن تقوم بنسخ/استنساخ المشروع.

إنشاء مسار باستخدام إضافة file-proxy

لاستخدام واختبار إضافة file-proxy الجديدة، نحتاج إلى إنشاء مسار في APISIX يستخدم الإضافة:

curl "http://127.0.0.1:9180/apisix/admin/routes/open-api-definition" -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
   "name":"OpenAPI Definition",
   "desc":"Route for OpenAPI Definition file",
   "uri":"/openapi.yaml",
   "plugins":{
      "file-proxy":{
         "path":"/usr/local/apisix/conf/openapi.yaml"
      }
   }
}'

يمكنك أن تطلب من ChatGPT شرح التكوين أعلاه:

شرح كود Lua باستخدام ChatGPT

اختبار الإضافة

ثم، يمكنك إرسال طلب cURL إلى المسار أو فتح الرابط http://127.0.0.1:9080/openapi.yaml في متصفحك. يجب أن تكون الاستجابة هي محتوى الملف openapi.yaml في العنوان URL المحدد.

curl -i http://127.0.0.1:9080/openapi.yaml

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

ملخص

تطوير إضافات مخصصة لـ APISIX باستخدام Lua هو طريقة قوية لتوسيع وظائف بوابة API. لقد أوضحنا كيفية إنشاء إضافة file-proxy في هذا المنشور، وحددنا تعريف الإضافة والمخطط، وتحققنا من تكوين الإضافة، ونفذنا منطقًا مخصصًا خلال مراحل الوصول والتسجيل في خط معالجة الطلبات في APISIX. ساعدنا ChatGPT في كتابة كود Lua للوظيفة الرئيسية عن طريق ملء معرفتنا الناقصة بهذه اللغة البرمجية. تمنياتنا بالبرمجة السعيدة!

موارد ذات صلة

Tags: