أنت الآن بصدد الاطّلاع على مستندات Apigee Edge.
انتقِل إلى
مستندات Apigee X. info
في هذا الموضوع، ستتعرّف على كيفية إنشاء مقاطع ريمكس باستخدام تركيب السياسات. تركيب السياسات هو نمط خادم وكيل في Apigee يتيح لك دمج نتائج من عدّة خوادم خلفية مستهدَفة في ردّ واحد باستخدام السياسات.
للحصول على نظرة عامة حول تركيبة السياسة، راجِع "نمط تركيبة السياسة" في أنماط "كتاب طبخ" لخادم وكيل لواجهة برمجة التطبيقات.
تنزيل الرمز النموذجي وتجربته
لمحة عن مثال كتاب الطبخ هذا
يوضّح مثال دليل الطبخ هذا نمطًا لوكيل واجهة برمجة التطبيقات يُعرف باسم تركيب السياسات. يوفّر هذا النمط طريقة واحدة (هناك طرق أخرى) لدمج البيانات من مصادر خلفية متعددة. بشكل عام، يوضّح هذا الموضوع كيف يمكن دمج السياسات وربطها ببعضها البعض لتحقيق النتيجة المطلوبة. للحصول على نظرة عامة على هذا النمط والأنماط الأخرى ذات الصلة، راجِع أنماط كتاب الطبخ الخاص بخادم وكيل لواجهة برمجة التطبيقات.
يستخدم المثال الموضّح هنا تركيبة السياسات لدمج البيانات من واجهتَي برمجة التطبيقات العامة المنفصلتَين التاليتَين:
- واجهة برمجة التطبيقات Google Geocoding API: تحوّل واجهة برمجة التطبيقات هذه العناوين (مثل "1600 Amphitheatre Parkway, Mountain View, CA") إلى إحداثيات جغرافية (مثل خط العرض 37.423021 وخط الطول -122.083739).
- واجهة Google Elevation API: توفّر هذه الواجهة واجهة بسيطة للاستعلام عن بيانات الارتفاع عن سطح البحر للمواقع الجغرافية على الأرض. في هذا المثال، سيتم استخدام الإحداثيات التي تم إرجاعها من Geocoding API كمدخلات في واجهة برمجة التطبيقات هذه.

سيطلب مطوّرو التطبيقات من خادم وكيل واجهة برمجة التطبيقات هذا استخدام مَعلمتَي طلب بحث، وهما الرمز البريدي ومعرّف البلد:
$ curl "http://{myorg}-test.apigee.net/policy-mashup-cookbook?country=us&postalcode=08008"
الردّ هو عنصر JSON يتضمّن الموقع الجغرافي المرمّز جغرافيًا (خط العرض/خط الطول) لمركز منطقة الرمز البريدي المقدَّم، بالإضافة إلى الارتفاع عند هذا الموقع الجغرافي المرمّز جغرافيًا.
{
"ElevationResponse":{
"status":"OK",
"result":{
"location":{
"lat":"39.7500713",
"lng":"-74.1357407"
},
"elevation":"0.5045232",
"resolution":"76.3516159"
}
}
}قبل البدء
إذا أردت الاطّلاع على نظرة عامة موجزة حول نمط إنشاء السياسات، راجِع "نمط إنشاء السياسات" في أنماط دليل API Proxy Cookbook.
قبل استكشاف مثال كتاب الطبخ هذا، يجب أن تكون على دراية أيضًا بالمفاهيم الأساسية التالية:
- السياسات وكيفية إرفاقها بخوادم وكيلة للحصول على مقدّمة جيدة حول السياسات، راجِع مقالة ما هي السياسة؟.
- بنية مسار الخادم الوكيل لواجهة برمجة التطبيقات، كما هو موضّح في ضبط المسارات تتيح لك التدفقات تحديد التسلسل الذي يتم به تنفيذ السياسات من خلال خادم وكيل لواجهة برمجة التطبيقات. في هذا المثال، يتم إنشاء عدة سياسات وإضافتها إلى مسار خادم وكيل واجهة برمجة التطبيقات.
- طريقة تنظيم مشروع خادم وكيل لواجهة برمجة التطبيقات في نظام الملفات، كما هو موضّح في مرجع إعدادات خادم وكيل لواجهة برمجة التطبيقات يوضّح موضوع كتاب الطبخ هذا عملية التطوير المحلية (المستندة إلى نظام الملفات) بدلاً من عملية التطوير المستندة إلى السحابة الإلكترونية التي يمكنك فيها استخدام واجهة مستخدم الإدارة لتطوير خادم وكيل لواجهة برمجة التطبيقات.
- استخدام التحقّق من صحة مفتاح واجهة برمجة التطبيقات هذا هو أبسط شكل من أشكال الأمان المستند إلى التطبيقات الذي يمكنك إعداده لواجهة برمجة تطبيقات. لمزيد من المعلومات، يُرجى الاطّلاع على مفاتيح واجهة برمجة التطبيقات. يمكنك أيضًا الاطّلاع على البرنامج التعليمي تأمين واجهة برمجة تطبيقات من خلال طلب مفاتيح واجهة برمجة التطبيقات.
- معرفة عملية بتنسيق XML في هذا المثال، ننشئ خادم وكيل لواجهة برمجة التطبيقات وسياساته باستخدام ملفات XML مخزّنة في نظام الملفات.
إذا كنت قد نزّلت الرمز النموذجي، يمكنك العثور على جميع الملفات التي تم تناولها في هذا الموضوع في مجلد النموذج mashup-policy-cookbook. تتناول الأقسام التالية الرمز النموذجي بالتفصيل.
الاستمتاع باللحظة
قبل الانتقال إلى السياسات، لنلقِ نظرة على التدفق الرئيسي لنموذج خادم وكيل واجهة برمجة التطبيقات. يخبرنا ملف XML الخاص بسير العمل، الموضّح أدناه، الكثير عن هذا الخادم الوكيل والسياسات التي يستخدمها ومكان استدعاء هذه السياسات.
في نموذج التنزيل، يمكنك العثور على ملف XML هذا في الملف
doc-samples/policy-mashup-cookbook/apiproxy/proxies/default.xml.
<ProxyEndpoint name="default"> <Flows> <Flow name="default"> <Request> <!-- Generate request message for the Google Geocoding API --> <Step><Name>GenerateGeocodingRequest</Name></Step> <!-- Call the Google Geocoding API --> <Step><Name>ExecuteGeocodingRequest</Name></Step> <!-- Parse the response and set variables --> <Step><Name>ParseGeocodingResponse</Name></Step> <!-- Generate request message for the Google Elevation API --> <Step><Name>AssignElevationParameters</Name></Step> </Request> <Response> <!-- Parse the response message from the Elevation API --> <Step><Name>ParseElevationResponse</Name></Step> <!-- Generate the final JSON-formatted response with JavaScript --> <Step><Name>GenerateResponse</Name></Step> </Response> </Flow> </Flows> <HTTPProxyConnection> <!-- Add a base path to the ProxyEndpoint for URI pattern matching--> <BasePath>/policy-mashup-cookbook</BasePath> <!-- Listen on both HTTP and HTTPS endpoints --> <VirtualHost>default</VirtualHost> <VirtualHost>secure</VirtualHost> </HTTPProxyConnection> <RouteRule name="default"> <!-- Connect ProxyEndpoint to named TargetEndpoint under /targets --> <TargetEndpoint>default</TargetEndpoint> </RouteRule> </ProxyEndpoint>
في ما يلي ملخّص لعناصر مسار الإحالة الناجحة:
- <Request>: يتألف العنصر <Request> من عدة عناصر <Step>. تستدعي كل خطوة إحدى السياسات التي سننشئها خلال بقية هذا الموضوع. تتعلّق هذه السياسات بإنشاء رسالة طلب وإرسالها وتحليل الردّ. في نهاية هذا الموضوع، ستتعرّف على دور كل من هذه السياسات.
- <Response>: يتضمّن العنصر <Response> أيضًا <Steps>. وتستدعي هذه الخطوات أيضًا السياسات المسؤولة عن معالجة الرد النهائي من نقطة النهاية المستهدَفة (Google Elevation API).
- <HttpProxyConnection> - يحدّد هذا العنصر تفاصيل حول كيفية اتصال التطبيقات بخادم وكيل لواجهة برمجة التطبيقات هذا، بما في ذلك <BasePath> الذي يحدّد كيفية استدعاء واجهة برمجة التطبيقات هذه.
- <RouteRule>: يحدّد هذا العنصر ما يحدث مباشرةً بعد معالجة رسائل الطلبات الواردة. في هذه الحالة، يتم استدعاء TargetEndpoint. سنتحدّث أكثر عن هذه الخطوة المهمة لاحقًا في هذا الموضوع.
إنشاء السياسات
تتناول الأقسام التالية كل سياسة من السياسات التي يتكوّن منها مثال تركيبة السياسات هذا.
إنشاء سياسة AssignMessage الأولى
تنشئ سياسة AssignMessage الأولى، المدرَجة أدناه، رسالة طلب سيتم إرسالها إلى خدمة الترميز الجغرافي من Google.

لنبدأ برمز السياسة، ثم سنشرح عناصرها بمزيد من التفصيل. في نموذج التنزيل، يمكنك العثور على ملف XML هذا في الملف doc-samples/policy-mashup-cookbook/apiproxy/policies/GenerateGeocodingRequest.xml.
<AssignMessage name="GenerateGeocodingRequest"> <AssignTo createNew="true" type="request">GeocodingRequest</AssignTo> <Set> <QueryParams> <QueryParam name="address">{request.queryparam.postalcode}</QueryParam> <QueryParam name="region">{request.queryparam.country}</QueryParam> <QueryParam name="sensor">false</QueryParam> </QueryParams> <Verb>GET</Verb> </Set> <!-- Set variables for use in the final response --> <AssignVariable> <Name>PostalCode</Name> <Ref>request.queryparam.postalcode</Ref> </AssignVariable> <AssignVariable> <Name>Country</Name> <Ref>request.queryparam.country</Ref> </AssignVariable> </AssignMessage>
في ما يلي وصف موجز للعناصر الواردة في هذه السياسة. يمكنك الاطّلاع على مزيد من المعلومات حول هذه السياسة في سياسة "تعيين رسالة".
- <AssignMessage name>: يمنح هذه السياسة اسمًا. يُستخدم الاسم عند الإشارة إلى السياسة في أحد المسارات.
- <AssignTo>: تنشئ هذه السمة متغيّرًا باسم GeocodingRequest. يغلّف هذا المتغيّر عنصر الطلب الذي سيتم إرساله إلى الخلفية من خلال سياسة ServiceCallout.
- <QueryParams>: تضبط هذه السياسة معلَمات طلب البحث التي يحتاجها طلب البيانات من واجهة برمجة التطبيقات الخلفية. في هذه الحالة، يجب أن تعرف Geocoding API الموقع الجغرافي، والذي يتم التعبير عنه برمز بريدي ومعرّف بلد. يقدّم مستخدم التطبيق هذه المعلومات، ونحن نستخرجها فقط. تتطلّب واجهة برمجة التطبيقات المَعلمة
sensor، ويجب أن تكون قيمتها صحيحة أو خطأ، ونضبطها هنا على خطأ. - <Verb>: في هذه الحالة، نُجري طلب استرداد بيانات باستخدام GET بسيطًا إلى واجهة برمجة التطبيقات.
- <AssignVariable>: تخزِّن هذه المتغيرات القيم التي نمرّرها إلى واجهة برمجة التطبيقات. في هذا المثال، سيتم الوصول إلى المتغيرات لاحقًا في الرد الذي تم إرجاعه إلى العميل.
إرسال الطلب باستخدام ServiceCallout
الخطوة التالية في تسلسل إنشاء السياسات هي إنشاء سياسة ServiceCallout. ترسل سياسة ServiceCallout، المذكورة أدناه، عنصر الطلب الذي أنشأناه في سياسة AssignMessage السابقة إلى خدمة الترميز الجغرافي من Google، وتحفظ النتيجة في متغير باسم GeocodingResponse.

كما في السابق، لنلقِ نظرة على التعليمات البرمجية أولاً. في ما يلي شرح مفصّل. يمكنك الاطّلاع على مزيد من المعلومات حول هذه السياسة في سياسة وسيلة الشرح الخاصة بالخدمة. في نموذج التنزيل، يمكنك العثور على ملف XML هذا في الملف
doc-samples/policy-mashup-cookbook/apiproxy/policies/ExecuteGeocodingRequest.xml.
<ServiceCallout name="ExecuteGeocodingRequest"> <Request variable="GeocodingRequest"/> <Response>GeocodingResponse</Response> <HTTPTargetConnection> <URL>http://maps.googleapis.com/maps/api/geocode/json</URL> </HTTPTargetConnection> </ServiceCallout>
في ما يلي وصف موجز لعناصر هذه السياسة.
- <ServiceCallout>: كما هو الحال مع السياسة السابقة، تتضمّن هذه السياسة اسمًا.
- <Request variable>: هذا هو المتغيّر الذي تم إنشاؤه في سياسة AssignMessage. وهي تتضمّن الطلب الذي يتم إرساله إلى واجهة برمجة التطبيقات الخلفية.
- <Response>: يحدّد هذا العنصر اسم متغيّر يتم تخزين الرد فيه. كما سترى، سيتم الوصول إلى هذا المتغير لاحقًا من خلال سياسة ExtractVariables.
- <HTTPTargetConnection>: تحدّد عنوان URL المستهدف لواجهة برمجة التطبيقات الخلفية. في هذه الحالة، نحدّد أنّ على واجهة برمجة التطبيقات عرض استجابة JSON.
لدينا الآن سياستان، إحداهما تحدّد معلومات الطلب اللازمة لاستخدام واجهة برمجة التطبيقات الخلفية (Geocoding API من Google)، والأخرى ترسل الطلب فعليًا إلى واجهة برمجة التطبيقات الخلفية. بعد ذلك، سنتولّى الردّ.
تحليل الرد باستخدام ExtractVariables
توفّر سياسة ExtractVariables آلية بسيطة لتحليل المحتوى من رسالة الرد التي تم الحصول عليها من خلال سياسة ServiceCallout. يمكن استخدام ExtractVariables لتحليل JSON أو XML، أو يمكن استخدامها لاستخراج محتوى من مسارات URI وعناوين HTTP ومعلمات طلب البحث ومعلمات النموذج.

في ما يلي قائمة بسياسة ExtractVariables. يمكنك الاطّلاع على مزيد من المعلومات حول هذه السياسة في سياسة "استخراج المتغيرات". في نموذج التنزيل، يمكنك العثور على ملف XML هذا في الملف
doc-samples/policy-mashup-cookbook/apiproxy/policies/ParseGeocodingResponse.xml.
<ExtractVariables name="ParseGeocodingResponse"> <Source>GeocodingResponse</Source> <VariablePrefix>geocoderesponse</VariablePrefix> <JSONPayload> <Variable name="latitude"> <JSONPath>$.results[0].geometry.location.lat</JSONPath> </Variable> <Variable name="longitude"> <JSONPath>$.results[0].geometry.location.lng</JSONPath> </Variable> </JSONPayload> </ExtractVariables>
في ما يلي العناصر الأساسية لسياسة ExtractVariable:
- <ExtractVariables name>: مرة أخرى، يتم استخدام اسم السياسة للإشارة إلى السياسة عند استخدامها في أحد التدفقات.
- <Source>: تحدّد متغيّر الرد الذي أنشأناه في سياسة ServiceCallout. هذا هو المتغيّر الذي تستخرج منه هذه السياسة البيانات.
- <VariablePrefix>: تحدّد بادئة المتغيّر مساحة اسم للمتغيّرات الأخرى التي تم إنشاؤها في هذه السياسة. يمكن أن يكون البادئة أي اسم، باستثناء الأسماء المحجوزة المحدّدة بواسطة متغيّرات Edge المحدّدة مسبقًا.
- <JSONPayload>: يسترد هذا العنصر بيانات الاستجابة التي تهمّنا ويضعها في متغيرات مسماة. في الواقع، تعرض Geocoding API معلومات أكثر بكثير من خطوط الطول والعرض. ومع ذلك، هذه هي القيم الوحيدة التي نحتاجها لهذا النموذج. يمكنك الاطّلاع على عرض كامل لملف JSON الذي تعرضه Geocoding API في مستندات واجهة برمجة التطبيقات. قيمتَا geometry.location.lat وgeometry.location.lng هما ببساطة حقلان من بين العديد من الحقول في عنصر JSON الذي يتم عرضه.
قد لا يكون ذلك واضحًا، ولكن من المهم ملاحظة أنّ ExtractVariables تنتج متغيرَين يتألف اسماهما من بادئة المتغير (geocoderesponse) وأسماء المتغيرات الفعلية المحددة في السياسة. يتم تخزين هذه المتغيرات في خادم وكيل لواجهة برمجة التطبيقات وستكون متاحة لسياسات أخرى ضمن تدفق الخادم الوكيل، كما سترى. المتغيرات هي:
- geocoderesponse.latitude
- geocoderesponse.longitude
تم الآن إنجاز معظم العمل. لقد أنشأنا مجموعة من ثلاث سياسات تشكّل طلبًا، وتتصل بواجهة برمجة تطبيقات خلفية، وتحلّل بيانات JSON التي تم عرضها. في الخطوات النهائية، سنقدّم البيانات من هذا الجزء من المسار إلى سياسة AssignMessage أخرى، وسنطلب من واجهة برمجة التطبيقات الثانية للخادم الخلفي (Google Elevation API)، وسنعرض البيانات المدمجة لمطوّر التطبيق.
إنشاء الطلب الثاني باستخدام AssignMessage
تستخدم سياسة AssignMessage التالية متغيرات تم إرجاعها من الخلفية الأولى (Google Geocoding) التي خزّناها، وتدرجها في طلب متّجه إلى واجهة برمجة التطبيقات الثانية (Google Elevation). كما ذكرنا سابقًا، هذان المتغيّران هما geocoderesponse.latitude وgeocoderesponse.longitude.
في نموذج التنزيل، يمكنك العثور على ملف XML هذا في الملف
doc-samples/policy-mashup-cookbook/apiproxy/policies/AssignElevationParameters.xml.
<AssignMessage name="AssignElevationParameters">
<Remove>
<QueryParams>
<QueryParam name="country"/>
<QueryParam name="postalcode"/>
</QueryParams>
</Remove>
<Set>
<QueryParams>
<QueryParam name="locations">{geocoderesponse.latitude},{geocoderesponse.longitude}</QueryParam>
<QueryParam name="sensor">false</QueryParam>
</QueryParams>
</Set>
</AssignMessage>إذا فحصت Google Elevation API، ستلاحظ أنّها تتضمّن مَعلمتَي طلب بحث.
الأولى تحمل الاسم locations وقيمتها هي خطوط الطول والعرض (قيم مفصولة بفواصل). المَعلمة الأخرى هي sensor، وهي مطلوبة ويجب أن تكون قيمتها إما "صحيح" أو "خطأ". أهم شيء يجب ملاحظته في هذه المرحلة هو أنّ رسالة الطلب التي ننشئها هنا لا تتطلّب ServiceCallout. لا نحتاج إلى طلب واجهة برمجة التطبيقات الثانية من ServiceCallout في هذه المرحلة لأنّه يمكننا طلب واجهة برمجة التطبيقات الخلفية من TargetEndpoint للوكيل. إذا فكّرت في الأمر، ستجد أنّ لدينا كل البيانات التي نحتاج إليها لاستدعاء واجهة برمجة التطبيقات Google Elevations، ولا تتطلّب رسالة الطلب التي تم إنشاؤها في هذه الخطوة ServiceCallout، لأنّ الطلب تم إنشاؤه لخط أنابيب الطلب الرئيسي، وبالتالي سيتم ببساطة إعادة توجيهه من خلال ProxyEndpoint إلى TargetEndpoint، وذلك باتّباع RouteRule الذي تم إعداده لوكيل واجهة برمجة التطبيقات هذا.
يدير TargetEndpoint عملية الربط بواجهة برمجة التطبيقات البعيدة. (تذكَّر أنّ عنوان URL الخاص بواجهة برمجة التطبيقات الخاصة بالارتفاع محدّد في HTTPConnection الخاص بـ TargetEndpoint. مستندات Elevation API إذا أردت معرفة المزيد. لم تعُد QueryParams التي خزّناها سابقًا،
أي country وpostalcode، ضرورية، لذا سنزيلها
هنا.
توقّف مؤقّت قصير: الرجوع إلى المسار
في هذه المرحلة، قد تتساءل عن سبب عدم إنشاء سياسة ServiceCallout أخرى. بعد
كل ذلك، أنشأنا رسالة أخرى. كيف يتم إرسال هذه الرسالة إلى الهدف، أي واجهة Google
Elevation API؟ تتوفّر الإجابة في العنصر <RouteRule> في التدفق. تحدّد <RouteRule> الإجراء الذي سيتم اتخاذه بشأن أي رسائل طلب متبقية بعد تنفيذ جزء <Request> من عملية التنفيذ. تخبر TargetEndpoint المحدّدة بواسطة <RouteRule> وكيل واجهة برمجة التطبيقات بتسليم الرسالة إلى http://maps.googleapis.com/maps/api/elevation/xml.
إذا نزّلت نموذج خادم وكيل لواجهة برمجة التطبيقات، يمكنك العثور على ملف XML الخاص بـ TargetProxy في الملف
doc-samples/policy-mashup-cookbook/apiproxy/targets/default.xml.
<TargetEndpoint name="default"> <HTTPTargetConnection> <!-- This is where we define the target. For this sample we just use a simple URL. --> <URL>http://maps.googleapis.com/maps/api/elevation/xml</URL> </HTTPTargetConnection> </TargetEndpoint>
الآن، ما علينا سوى معالجة الردّ من Google Elevation API، وبذلك نكون قد انتهينا.
تحويل الردّ من XML إلى JSON
في هذا المثال، يتم عرض الردّ من Google Elevation API بتنسيق XML. بالنسبة إلى "الرصيد الإضافي"، لنضِف سياسة أخرى إلى السياسة المركّبة لتحويل الردّ من XML إلى JSON.
يستخدم هذا المثال سياسة JavaScript باسم GenerateResponse، مع ملف موارد يحتوي على رمز JavaScript، لإجراء عملية التحويل. في ما يلي تعريف سياسة GenerateResponse:
<Javascript name="GenerateResponse" timeout="10000"> <ResourceURL>jsc://GenerateResponse.js</ResourceURL> </Javascript>
يتضمّن ملف الموارد GenerateResponse.js رمز JavaScript المستخدَم لإجراء عملية التحويل. يمكنك الاطّلاع على هذا الرمز في الملف doc-samples/policy-mashup-cookbook/apiproxy/resources/JSC/GenerateResponse.js.
توفّر Apigee أيضًا سياسة جاهزة للاستخدام، وهي XMLToJSON، لتحويل XML إلى JSON. يمكنك تعديل ProxyEndpoint لاستخدام سياسة xmltojson الموضّحة أدناه بدلاً من ذلك.
<XMLToJSON name="xmltojson"> <Options> </Options> <OutputVariable>response</OutputVariable> <Source>response</Source> </XMLToJSON>
اختبار المثال
إذا لم يسبق لك إجراء ذلك، حاوِل تنزيل نموذج policy-mashup-cookbook ونشره وتشغيله، ويمكنك العثور عليه في المجلد doc-samples في مستودع نماذج Apigee Edge على GitHub. ما عليك سوى اتّباع التعليمات الواردة في ملف README في مجلد policy-mashup-cookbook. أو اتّبِع التعليمات الموجزة هنا: استخدام عيّنات خوادم API الوكيلة.
باختصار، يمكنك طلب بيانات من واجهة برمجة التطبيقات المركّبة على النحو التالي. استبدِل {myorg} باسم مؤسستك:
$ curl "http://{myorg}-test.apigee.net/policy-mashup-cookbook?country=us&postalcode=08008"
يتضمّن الردّ الموقع الجغرافي المرمّز لمركز الرمز البريدي الذي يقدّمه مستخدم التطبيق النهائي، بالإضافة إلى الارتفاع عند هذا الموقع الجغرافي المرمّز. تم استرداد البيانات من واجهتَي برمجة تطبيقات للخادم الخلفي، وتم دمجها مع السياسات المرفقة بخادم وكيل لواجهة برمجة التطبيقات، وتم إرجاعها إلى العميل في ردّ واحد.
{ "country":"us", "postalcode":"08008", "elevation":{ "meters":0.5045232, "feet":1.6552599030345978 }, "location":{ "latitude":39.75007129999999, "longitude":-74.1357407 } }
ملخّص
شرح موضوع كتاب الطبخ هذا كيفية استخدام نمط تركيب السياسات لإنشاء مزيج من البيانات من مصادر خلفية متعددة. تركيب السياسات هو نمط شائع يُستخدم في تطوير خادم وكيل لواجهة برمجة التطبيقات من أجل إضافة وظائف إبداعية إلى واجهة برمجة التطبيقات.