تصميم واجهة برمجة تطبيقات نقل الملفات: ممارسات RESTful
صمّم واجهات برمجة تطبيقات قوية لنقل الملفات وفق أفضل ممارسات RESTful. المصادقة وتحديد المعدل والتحميل المتعدد ومعالجة الأخطاء.
واجهة برمجة REST لنقل الملفات مصمَّمة بشكل جيد تكشف خمسة أو ستة موارد (جلسات وأجزاء ومشاركات وتنزيلات وإلغاءات)، وتستخدم دلالات HTTP بصدق (POST للإنشاء، وPUT للأجزاء المتبادلة، وDELETE للإلغاء)، وتدفع حركة البايتات الفعلية إلى عناوين URL التخزين الموقَّعة مسبقاً حتى لا يصبح خادمك عنق زجاجة نطاق ترددي. المصادقة تستخدم رموز حاملة قصيرة الأجل عبر TLS 1.3، وتحديد المعدل يُميِّز بين الإنشاء وقراءة البيانات الوصفية، والرفع المجزأ يتبع نمط tus القابل للاستئناف أو دلالات S3 متعدد الأجزاء، والأخطاء تتبع RFC 7807 Problem Details حتى يتمكن العملاء من التصرف بناءً عليها برمجياً.
شكِّل نموذج الموارد حول الإجراءات لا الملفات
خطأ شائع هو نمذجة الـ API كشجرة ملفات. خدمات نقل الملفات تُنمذَج بشكل أفضل كثلاثة موارد:
/sessions— رفع جارٍ، يُنشأ بـ POST، يُملأ عبر PUT للأجزاء/shares— نقل مكتمل وقابل للعنونة مع انتهاء صلاحية وميزانية تنزيل/downloads— مقابض وصول موقَّعة قصيرة الأجل لجلب البايتات
الجلسات تصبح مشاركات عبر إجراء complete؛ المشاركات تنتهي صلاحيتها بالوقت أو ميزانية التنزيل. الإلغاءات هي PATCH على مشاركة أو DELETE برمز إلغاء. لا أسماء لـ "ملف" أو "مجلد" — تلك تفاصيل تنفيذ التخزين لا عقدك العام.
هذا الشكل يُبقي سطح الـ API صغيراً (أقل من 10 نقاط نهاية)، يُعيَّن بنظافة على تخزين HTTP المؤقت (المشاركات Cache-Control: private, max-age=60؛ التنزيلات no-store)، ويتيح استبدال خلفيات التخزين بدون كسر العملاء.
أنماط المصادقة والتفويض
لـ APIs التي يواجهها المستخدمون، أصدِر JWTs قصيرة الأجل (TTL 15 دقيقة) موقَّعة بـ EdDSA، وجدِّد عبر كوكي HttpOnly آمن. ضع الرمز في Authorization: Bearer، أبداً في سلاسل استعلام حيث يُسجَّل.
لـ machine-to-machine، توقيع الطلبات HMAC-SHA256 يتفوق على رموز الحاملين لأنه يُثبِت امتلاك المفتاح بدون إرساله. AWS SigV4 هو التصميم المرجعي:
Authorization: HEX4-HMAC-SHA256
Credential=AKIA.../20261202/eu/transfer/hex4_request,
SignedHeaders=host;x-hex-date;x-hex-content-sha256,
Signature=...
لعناوين URL التنزيل الموقَّعة مسبقاً، TTL يجب أن يكون بالدقائق لا الساعات. نافذة 15 دقيقة تُوازن قابلية الاستخدام مع خطر تمرير عنوان URL مُسرَّب. أضِف قفل IP فقط إذا كنت تستطيع تحمل كسر مستخدمين خلف CGNAT — عادةً لا تستطيع.
الرفع المجزأ ودلالات متعدد الأجزاء
بروتوكولان موثوقان موجودان للرفع المجزأ القابل للاستئناف: tus (مسودة IETF، ترويسات Upload-Offset وUpload-Length) وS3 متعدد الأجزاء (PartNumber وUploadId وETag). اختر واحداً وألتزم به. اختراع بروتوكولك الخاص يبدو جذاباً وينتهي بشكل سيئ حين تدرك أنك بحاجة للتعامل مع الكتابات الجزئية والأجزاء خارج الترتيب والجلسات المهجورة.
نمط tus في شكل REST:
POST /sessions -> 201, Location: /sessions/abc
HEAD /sessions/abc -> 200, Upload-Offset: 104857600
PATCH /sessions/abc -> 204, body = next chunk
POST /sessions/abc/complete -> 201, Location: /shares/xyz
DELETE /sessions/abc -> 204
حدود حجم الجزء: 5 ميجابايت كحد أدنى لمطابقة S3 متعدد الأجزاء، 100 ميجابايت كحد أقصى لإبقاء تكلفة إعادة المحاولة محدودة، 8 ميجابايت افتراضياً. ارفض الأجزاء التي لا تتوافق مع الإزاحة المُعلَنة بـ HTTP 409 Conflict بالإضافة إلى وثيقة Problem توضح الإزاحة المتوقعة.
تحديد المعدل الذي يعكس الإساءة الحقيقية
حدود المعدل تحتاج تنويعاً حسب تكلفة نقطة النهاية:
POST /sessions: 20 لكل IP في الساعة (مكلف — يُخصِّص تخزيناً)PATCH /sessions/:id: 10,000 في الساعة لكل جلسة (رخيص — يكتب بايتات)GET /shares/:id: 1,000 لكل IP في الساعة (بحث في البيانات الوصفية)GET /shares/:id/download: 100 لكل IP في الساعة (تكلفة خروج)
طبِّق الحدود على الحافة (Cloudflare وFastly) للحماية الأساسية، وطبقة ثانية على التطبيق (express-rate-limit، @fastify/rate-limit من Fastify) للتحكم في الانفجارات. أعِد 429 مع Retry-After بالثواني. أضِف ترويسات تحديد المعدل على الاستجابات الناجحة أيضاً:
RateLimit-Limit: 20
RateLimit-Remaining: 17
RateLimit-Reset: 2843
اتباع مسودة IETF RateLimit يتيح للعملاء المُنضبطين تنظيم معدلهم بدلاً من حجبهم.
استجابات الخطأ التي يمكن للعملاء التصرف بناءً عليها
RFC 7807 Problem Details هو المعيار. كل خطأ يُعيد Content-Type: application/problem+json:
{
"type": "https://api.example.com/errors/chunk-offset-mismatch",
"title": "Chunk offset mismatch",
"status": 409,
"detail": "Server expected offset 5242880, received 4194304.",
"expected_offset": 5242880,
"session_id": "abc123"
}
type URI يجب توثيقه وثباته؛ هذا ما يُطابقه العملاء نمطياً. title عام؛ detail محدد. الحقول المخصصة تضيف سياقاً قابلاً للتنفيذ آلياً. لا تُسرِّب أبداً آثار المكدس أو مسارات الملفات أو المعرِّفات الداخلية في الأخطاء.
عيِّن رموز HTTP بصدق: 400 للمدخلات ذات الصيغة الخاطئة، 401 للمصادقة المفقودة، 403 للمُصادَق عليه لكن غير المُفوَّض، 404 فقط حين لم يوجد المورد قط (استخدم 410 Gone للمشاركات المنتهية صلاحيتها)، 413 للحمولات التي تتجاوز الحصة، 429 لحدود المعدل، 500 للأخطاء، 503 للصيانة.
التفاوض على المحتوى والتدفق
نقاط نهاية الرفع يجب أن تقبل application/octet-stream وتشترط Content-Length. ارفض multipart/form-data لرفع الأجزاء — يُضيف أعباء تحليل ولا يُفيد أحداً. اقبل Content-Range للكتابات الجزئية بنمط tus.
نقاط نهاية التنزيل يجب دعم طلبات HTTP Range (RFC 7233) للتنزيل القابل للاستئناف:
GET /shares/xyz/blob
Range: bytes=104857600-209715199
-> 206 Partial Content
Content-Range: bytes 104857600-209715199/2147483648
هذا ما يتيح للمتصفحات استئناف تنزيل 2 جيجابايت بعد انقطاع Wi-Fi. معظم مخازن S3 المتوافقة تخدم طلبات Range أصلياً — API الخاصة بك تحتاج فقط إعادة التوجيه أو التوقيع المسبق.
الإصدار بدون تراكم الديون
أصدِر عبر مسار URL (/v1/sessions) لا الترويسات. إصدار المسار مرئي في السجلات وقابل للتخزين المؤقت وأسهل في التصحيح من Accept: application/vnd.example.v1+json. حافظ على دعم v1 لـ 24 شهراً على الأقل بعد شحن v2. أضِف حقولاً بحرية (العملاء يجب أن يتجاهلوا الحقول المجهولة)؛ لا تُزِل أو تُعيد تسمية حقول في إصدار مستقر.
حين تكون التغييرات الجذرية ضرورية، شغِّل v1 وv2 بالتوازي 12 شهراً، أضِف ترويسة Sunset على استجابات v1 وفق RFC 8594، وانشر أدلة ترحيل بأمثلة قبل/بعد حقيقية.
قابلية المراقبة والتصحيح
كل استجابة يجب أن تتضمن معرِّف ارتباط (X-Request-ID) منعكساً من الطلب أو مُولَّداً. سجِّل المعرِّف وعنوان IP للعميل (مُبصَّم إذا كان حساسًا للخصوصية) ونقطة النهاية والحالة والمدة في JSON منظَّم. لا تسجِّل جسم الطلبات — هكذا تنتهي مفاتيح التشفير في Datadog.
أصدِر مقاييس لكل نقطة نهاية: عدد الطلبات، وتأخير p50/p95/p99، ومعدل الأخطاء، والبايتات داخل وخارج. نبِّه على ارتفاع تأخير p99 ومعدل 5xx فوق الخط الأساسي. التتبع عبر OpenTelemetry يمنحك تدفق الطلب عبر API والتخزين وقاعدة البيانات.
API الخاصة بـ HexaTransfer تتبع الأنماط أعلاه — موارد مختصرة، رفع مجزأ بنمط tus، أخطاء Problem Details، تنزيلات موقَّعة مسبقاً لـ 15 دقيقة، ترويسات RateLimit.
التوثيق الذي يتطابق مع الواقع
انشر مواصفة OpenAPI 3.1 جانب API واحتفظ بها في نفس مستودع كود الخادم حتى يكون انجراف المخطط مسألة مراجعة PR لا مفاجأة إنتاجية. أنشئ SDK واحداً على الأقل (TypeScript أو Python) من المواصفة واستخدمه في أمثلتك الخاصة — أخطاء SDK تكشف أخطاء المواصفة بسرعة. أضِف أمثلة curl لكل نقطة نهاية، وبداية سريعة ترفع ملفاً حقيقياً في أقل من 20 سطراً، وصفحة توثق خصيصاً كل URI لـtype في الأخطاء. API يستطيع المطورون دمجها في ساعة بعد ظهر ستصل إلى 10 أضعاف المنتجات مقارنةً بتلك التي تتطلب أسبوعاً من الهندسة العكسية.
جرّبها على hexatransfer.com — مجاناً، بدون حساب، حتى 10 جيجابايت.
أرسل ملفات كبيرة بأمان مع تشفير من طرف إلى طرف
انقل ملفات حتى 10 جيجابايت مجاناً مع تشفير من طرف إلى طرف. لا حاجة لحساب. يتم تشفير ملفاتك في متصفحك قبل الرفع — لا أحد آخر يستطيع قراءتها.
إرسال ملف