FlowingDev

من cURL إلى كود: ترجمة لغة الويب المشتركة

تعلم كيف يمكن ترجمة أوامر cURL، اللغة العالمية لطلبات الويب، إلى كود برمجي أصلي بلغات مثل JavaScript fetch و Python و Go و PHP.

جرّب الأداة: cURL إلى كود

في جملة واحدة

محوّل "cURL إلى كود" يترجم طلب ويب مكتوب بصيغة cURL العالمية من سطر الأوامر إلى كود مكافئ وجاهز للاستخدام بلغات مثل JavaScript أو Python أو Go.

المشكلة التي يحلها

في البداية، كان هناك التيرمينال. وفي التيرمينال، إذا أردت التحدث إلى الإنترنت، كنت بحاجة إلى أداة. في عام 1997، أنشأ مطور سويدي يدعى دانيال ستينبرغ أداة لجلب أسعار العملات لـ IRC bot. أطلق عليها اسم curl، اختصاراً لـ "Client for URL". ومنذ ذلك الحين، نمت لتصبح سكين الجيش السويسري لعمليات الشبكات بلا منازع—برنامج صغير، قوي بشكل لا يصدق، يمكنه التحدث ببروتوكولات HTTP، وFTP، وSMTP، وعشرات البروتوكولات الأخرى مباشرة من سطر الأوامر الخاص بك.

لأنها عالمية، وقائمة على النصوص، وقوية بشكل يبعث على السخرية، أصبحت curl المعيار الفعلي (de facto) لتوثيق استدعاءات الـ API. اختر أي API حديث—Stripe، GitHub، Twilio—وسيُظهر لك دليل "البدء" الخاص بهم أمر curl بشكل شبه مؤكد. إنها الطريقة المثالية والواضحة لقول: "هذا هو الطلب الدقيق الذي عليك إرساله إلى خادمنا".

هذا رائع... إلى أن تضطر فعلاً إلى كتابة الكود.

أنت تعمل على تطبيق React الخاص بك. وتقول المستندات: curl -X POST https://api.pizza.dev/orders -H 'Authorization: Bearer ...' --data '{"size":"large","toppings":["pepperoni","cheese"]}'

الآن عليك ترجمة ذلك يدوياً إلى استدعاء fetch في JavaScript. لنر... ما هو مقابل -X POST في fetch؟ حسناً، method: 'POST'. وماذا عن -H للـ header؟ هذا هو كائن headers. وماذا عن --data؟ هل هو الـ body؟ هل ألصق النص كما هو؟ أم أحتاج إلى JSON.stringify()؟ لحظة، ألا يجب أن يكون الـ Content-Type header هو application/json؟ أمر curl لم يكن يحتوي عليه! (حرق للأحداث: curl أحيانًا يضيفه نيابة عنك، وأحيانًا لا، حسب الـ flag المستخدم. ممتع، أليس كذلك؟)

هذه الترجمة اليدوية هي حقل ألغام من الأخطاء الصغيرة والمزعجة. إنها مملة، وعرضة للأخطاء، ومضيعة كاملة للطاقة العقلية. محول cURL إلى كود يحل هذه المشكلة من خلال العمل كمترجم مثالي وصبور. يأخذ اللغة العالمية لمستندات الـ API ويحولها إلى اللهجة المحددة التي يتحدث بها تطبيقك، مما يوفر لك الوقت، والأخطاء، والكثير من صرخات "لماذا أحصل على خطأ 400 Bad Request؟!" في الفراغ.

كيف يعمل تحت الغطاء

في جوهره، محول cURL إلى كود هو محلل نصوص (parser) متخصص. إنه لا يشغل أمر curl فعليًا. بدلاً من ذلك، يقرأ الأمر كسلسلة نصية ويقوم بتشريحها، رمزًا (token) تلو الآخر، ويربط كل جزء بمفهوم مقابل في لغة البرمجة المستهدفة.

دعنا نحلل ترجمة أمر معقد إلى حد ما:

curl -X POST 'https://api.example.com/v1/users' \
  -H 'Authorization: Bearer my-secret-token' \
  -H 'Content-Type: application/json' \
  --data-raw '{"name": "Alice", "role": "admin"}' \
  -L

سيقوم parser جيد بتحليل هذا الأمر على عدة مراحل.

### الأمر، الوسائط، والرابط (URL)

أولاً، يقسم الـ parser الأمر حسب المسافات، مع احترام علامات الاقتباس. يرى curl، و-X، وPOST، و'https://api.example.com/v1/users'، وهكذا.

  • curl: هذا يحدد نوع الأمر. يعرف الـ parser أنه يتعامل مع صيغة cURL.
  • 'https://api.example.com/v1/users': هذه هي أول وسيطة لا تبدأ بـ - (أي ليست flag). يحددها الـ parser بشكل صحيح على أنها الرابط المستهدف (URL). يصبح هذا هو الوسيط الأساسي لأي مكتبة HTTP تقريبًا.
// JavaScript fetch
fetch('https://api.example.com/v1/users', { /* ... options */ });
# Python requests
requests.post('https://api.example.com/v1/users', **options)

### الطريقة (Method): -X POST

الـ flag -X (أو --request) يحدد صراحة طريقة HTTP. يرى الـ parser -X ويعرف أن الـ token التالي، POST، هو الطريقة. إذا لم يكن هناك -X، فإنه يفترض GET (إلا إذا تم استخدام flag بيانات مثل -d، مما يعني ضمنيًا POST).

هذا يرتبط مباشرة بمعامل الطريقة في اللغة المستهدفة.

// JavaScript fetch
{
  method: 'POST'
}
// Go net/http
req, err := http.NewRequest("POST", url, ...)

### الترويسات (Headers): -H

الـ flag -H (أو --header) يمكن أن يظهر عدة مرات. يجمع الـ parser كل هذه الـ flags ويجمعها في بنية مفتاح-قيمة.

  • -H 'Authorization: Bearer my-secret-token' -> Authorization: Bearer my-secret-token
  • -H 'Content-Type: application/json' -> Content-Type: application/json

تصبح هذه المجموعة قاموسًا (dictionary)، أو خريطة (map)، أو كائنًا بسيطًا في الكود المُنشأ.

// JavaScript fetch
{
  headers: {
    'Authorization': 'Bearer my-secret-token',
    'Content-Type': 'application/json'
  }
}

### المحتوى (Body): --data-raw

هنا تصبح الأمور مثيرة للاهتمام وهنا تتألق المحولات الجيدة. لدى cURL العديد من الـ flags لإرسال البيانات:

  • -d, --data: يرسل البيانات بتشفير URL. يضبط Content-Type على application/x-www-form-urlencoded افتراضيًا.
  • --data-raw: يرسل البيانات تمامًا كما هي، دون أي معالجة إضافية.
  • --data-binary: يرسل البيانات في شكل ثنائي.
  • -F, --form: ينشئ طلب multipart/form-data، عادةً لرفع الملفات.

يستخدم مثالنا --data-raw، وهو مؤشر قوي على أن المحتوى (body) مُنسق مسبقًا، على الأرجح كـ JSON. يمسك الـ parser السلسلة التالية: '{"name": "Alice", "role": "admin"}'.

بعد ذلك، يضع المحول هذه السلسلة في محتوى الطلب. بالنسبة للغة مثل Python، يمكنه تمرير السلسلة مباشرة. بالنسبة لـ JavaScript، من الأفضل إظهار كائن JS أصلي للمستخدم ولفه في JSON.stringify().

// JavaScript fetch
{
  body: JSON.stringify({
    name: "Alice",
    role: "admin"
  })
}
# Python requests
# مكتبة 'requests' ذكية؛ إذا قمت بتوفير سلسلة نصية و content-type من نوع JSON...
# سترسل السلسلة. أو يمكنك استخدام المساعد json:
response = requests.post(url, headers=headers, json={"name": "Alice", "role": "admin"})

### Flags أخرى: -L

الـ flag -L (أو --location) يخبر curl بمتابعة عمليات إعادة التوجيه (redirects) في HTTP (على سبيل المثال، استجابة 301 أو 302). يربط الـ parser هذا بالخيار المكافئ في المكتبة المستهدفة.

// JavaScript fetch
{
  redirect: 'follow'
}

بجمع كل ذلك معًا، يُنشئ الـ parser كتلة كود كاملة وصحيحة من الناحية النحوية عن طريق تجميع هذه القطع المترجمة.

إليك خريطة مبسطة للـ flags الشائعة:

cURL Flag المعنى يُترجم إلى...
(لا يوجد flag) URL الوسيط الخاص بالرابط المستهدف
-X, --request طريقة HTTP (GET, POST, إلخ.) خاصية method، اسم الدالة
-H, --header ترويسة الطلب (Request Header) كائن/قاموس headers
-d, --data محتوى الطلب (Body) (مشفر بـ URL) خاصية body، معامل data
--data-raw محتوى الطلب (Body) (كما هو) خاصية body، معامل data
-u, --user مصادقة أساسية (Basic Authentication) ترويسة Authorization (Basic <base64>)
-L, --location متابعة إعادة التوجيه (Redirects) خيار redirect: 'follow'
--compressed طلب استجابة مضغوطة ترويسة Accept-Encoding
-i, --include تضمين ترويسات الاستجابة في المخرجات (يتم تجاهله؛ flag خاص بالمخرجات فقط)

قصص من الواقع

### مطورة الواجهات الأمامية والـ Flag الخادع

كانت كلوي، مطورة واجهات أمامية، تدمج API شحن تابع لجهة خارجية. قدمت المستندات أمر curl للحصول على عرض سعر للشحن. قامت بنسخ الـ headers وجسم الـ JSON بدقة في طلب fetch الخاص بها. كان يفشل في كل مرة مع خطأ 400 Bad Request. بعد ساعة من خبط رأسها في الحائط، لاحظت أن مثال curl استخدم -d، وليس --data-raw. كان طلب fetch الخاص بها يرسل JSON خام، لكن الخادم، متابعًا دلالات -d، كان يتوقع سلسلة نصية مشفرة بـ URL. كان تصميم الـ API سيئًا، لكن أمر curl كان صحيحًا من الناحية الفنية. محبطة، قامت بلصق الأمر في محول cURL. أخرج لها مقتطف JavaScript يلف البيانات بشكل صحيح في كائن URLSearchParams. نجح الطلب على الفور.

الدرس: يفهم محول cURL السلوكيات الدقيقة والضمنية لـ flags الأمر curl التي قد يفوتها حتى المطورون ذوو الخبرة، مما يوفر ساعات من تصحيح الأخطاء.

### مهندس DevOps و Webhook الثالثة فجراً

كان بن، مهندس DevOps، يقوم بإعداد نظام تنبيه للطوارئ. إذا ارتفع استهلاك وحدة المعالجة المركزية لقاعدة البيانات الرئيسية فوق 95% لمدة خمس دقائق، كان على سكربت أن يرسل رسالة إلى PagerDuty webhook. قدمت مستندات PagerDuty أمر curl نظيف. كانت أتمتة بن مكتوبة بلغة Go. كان بإمكانه قضاء 15 دقيقة في البحث عن صيغة net/http في Go، ومعرفة كيفية إنشاء طلب، وتعيين الـ headers، وإرفاق جسم JSON. بدلاً من ذلك، أسقط أمر curl في محول، واختار "Go"، وحصل على الكود الذي يحتاجه بالضبط في خمس ثوانٍ. قام بلصقه في السكربت الخاص به، واختبره، وانتقل إلى المهمة التالية.

الدرس: بالنسبة للسكربتات والأتمتة، تعد محولات cURL دفعة إنتاجية هائلة، حيث تقضي على تبديل السياق المطلوب للبحث عن صيغة عميل HTTP الخاصة باللغة.

### المبتدئ و "حجر رشيد"

كان سام يتعلم تطوير الويب وكان قد سمع للتو عن الـ APIs. كان مفهوم "كود يتحدث إلى كود آخر" لا يزال غامضًا. وجد API طقس مجاني وممتع، وأظهرت وثائقه أمر curl للحصول على توقعات الطقس في لندن. قام بتشغيله في التيرمينال ورأى تدفقًا من بيانات JSON يظهر. شعر وكأنه سحر! ولكن كيف يمكنه الحصول على تلك البيانات على صفحة ويب؟ قام بلصق أمر curl في محول ورأى كود fetch. فجأة، اتضح كل شيء. كان الـ URL من الأمر هو الوسيط الأول لـ fetch. أصبح الـ flag -H كائن headers. تحول الأمر التجريدي في التيرمينال إلى كتلة كود ملموسة وقابلة للقراءة يمكنه استخدامها مباشرة في مشروعه.

الدرس: يعمل محول cURL بمثابة "حجر رشيد"، حيث يسد الفجوة بين الأوامر المجردة والكود الفعلي، مما يجعله أداة لا تقدر بثمن للتعلم.

الأخطاء والفخاخ الشائعة

  • نسيان سياق الـ shell. أمر مثل curl "https://api.com?q=$USER" سيتم استبدال متغير $USER بواسطة الـ shell الخاص بك قبل أن يعمل curl حتى. المحول يرى فقط السلسلة "$USER" ولا يمكنه معرفة قيمتها. كن على دراية بتوسعات الـ shell وانسخ الأمر "النهائي".
  • فخ -d مقابل --data-raw. هذا هو الفخ الكلاسيكي. إذا كان الـ API الخاص بك يتوقع JSON، فأنت على الأرجح تريد --data-raw مع header Content-Type: application/json. استخدام -d سيقوم بتشفير الـ JSON الخاص بك بـ URL ({ تصبح %7B، " تصبح %22، إلخ)، مما سيؤدي إلى تعطل معظم APIs التي تتعامل مع JSON.
  • تجاهل رفع الملفات. تحويل طلب multipart/form-data (باستخدام -F أو --form) أمر صعب. يحتاج الكود الذي تم إنشاؤه إلى التعامل مع قراءة الملفات وإنشاء كائن FormData خاص. غالبًا ما تفشل المحولات البسيطة هنا، وتنتج كودًا يرسل اسم ملف كسلسلة نصية بدلاً من محتويات الملف.
  • الخلط بين flags الطلب و flags المخرجات. الـ flags مثل -v (verbose)، -s (silent)، أو -o file.txt (output to file) تتحكم في كيفية عرض curl للمعلومات. إنها ليست جزءًا من طلب HTTP المرسل إلى الخادم. يجب على المحول الجيد التعرف عليها وتجاهلها، حيث لا يوجد لها ما يعادلها في مكتبة عميل HTTP.
  • علامات الاقتباس المفردة مقابل المزدوجة. في bash والـ shells الأخرى، تعامل علامات الاقتباس المفردة (') محتوياتها حرفيًا، بينما تسمح علامات الاقتباس المزدوجة (") بتوسيع المتغيرات. يمكن أن يؤثر هذا على السلسلة التي يراها المحول بالفعل. تأكد دائمًا من أن ما تنسخه هو ما تنوي إرساله.

لماذا يجب أن تكون على رادارك

كل مطور يلامس الويب سيتعامل مع أمر curl عاجلاً أم آجلاً. معرفة كيفية ترجمتها بسرعة وموثوقية هي قوة خارقة.

  • عند استهلاك أي API: هذه هي حالة الاستخدام الأساسية. مستندات الـ API مكتوبة بـ curl. تطبيقك ليس كذلك. سد هذه الفجوة.
  • عند تصحيح أخطاء الشبكة: تتيح لك أدوات المطور في المتصفحات الحديثة النقر بزر الماوس الأيمن على أي طلب شبكة و "Copy as cURL". يمكنك بعد ذلك لصق هذا في محول لتكرار الطلب الدقيق من متصفحك في سكربت Python أو Node.js لتصحيح الأخطاء بشكل أكثر عزلًا وقوة.
  • عند كتابة الأتمتة والسكربتات: هل تحتاج إلى الوصول إلى endpoint من سكربت Python، أو أداة Go، أو وظيفة PHP cron؟ ابحث عن أمر curl وقم بتحويله. إنه أسرع من البحث عن الصيغة من الصفر في كل مرة.
  • عند تعلم لغة جديدة: إذا كنت تعرف curl ولكنك جديد على Axios، أو مكتبة requests في Python، أو net/http في Go، فإن المحول أداة تعليمية رائعة. يوضح لك الطريقة الاصطلاحية لعمل طلب مألوف في بيئة غير مألوفة.

تعمق أكثر

  • Everything cURL: الدليل النهائي لـ cURL، كتبه مبتكره، دانيال ستينبرغ.
  • curl Man Page: المرجع الرسمي الشامل لكل flag وخيار.
  • MDN: Using the Fetch API: الكتاب المقدس لعمل طلبات الويب في JavaScript الحديثة.
  • Python requests Quickstart: توثيق لما يمكن القول إنها مكتبة عميل HTTP الأكثر شعبية في أي لغة.
  • RFC 9110: HTTP Semantics: عندما تريد حقًا، حقًا، أن تعرف ما يحدث تحت غطاء HTTP نفسه.
  • Wikipedia: cURL: نظرة عامة عالية المستوى على تاريخ الأداة وقدراتها.

انتهينا من النظرية. حان وقت التطبيق — 100% في متصفحك.

جرّب الأداة: cURL إلى كود