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

أحد مشاريعنا هو تطبيق لشركة يانصيب كبيرة (لا يمكنني إعطاء اسم منذ التجمع الوطني). في الآونة الأخيرة ، كنت بحاجة إلى ترجمتها إلى GraphQL دون أن أفقد عقلي.
المشروع كبير جدًا - للوهلة الأولى ، كان من الضروري قضاء ما بين 200 و 300 ساعة على الأقل ، لكن هذا يتجاوز كل المسافات المحتملة لمدة أسبوعين. لم نتمكن أيضًا من تخصيص المسار الكامل لمهمة واحدة فقط ، نظرًا لوجود ميزات جانبية ، لا تقل أهمية عن GraphQL.
لقد فكرنا لفترة طويلة فيما يجب علينا فعله وقررنا ترجمة المشروع خطوة بخطوة ، نموذجًا تلو الآخر. مع هذا النهج ، سيكون الانتقال سلسًا ، وسيتم توزيع 200-300 ساعة على عدة سباقات.
النقاط الفنية
للعمل في المشروع ، استخدمت مكتبة أبولو.
يوجد بالفعل مقال عن حبري يصف كل التفاصيل الدقيقة للعمل معه ، لذلك لن أكرره مرة أخرى. أحذرك مقدمًا - العمل باستخدام نموذج تم إنشاؤه بالكود ليس ملائمًا جدًا ومن الأفضل الاحتفاظ به كـ "شبكة". يحتوي كل كيان على __typename: حقل السلسلة ، والذي ، بشكل غريب ، يُرجع اسم نوع.
تحلل المهمة
أول ما يجب فعله هو تحديد النموذج القديم الذي سنترجم إلى GraphQL. في حالتي ، كان من المنطقي ترجمة أحد نماذج GameInfo الضخمة ، و DrawInfo مضمن فيه.
- GameInfo - يحتوي على معلومات حول ألعاب اليانصيب وتوجه.
- DrawInfo - يحتوي على بيانات على التداول
بعد الانتهاء من الاختيار ، قررت تهيئة النماذج القديمة القديمة بنماذج جديدة تم الحصول عليها باستخدام GraphQL. مع هذا النهج ، ليس من الضروري استبدال تلك الأجزاء من التطبيق حيث يتم استخدام النموذج القديم. كان إكمال النماذج السابقة أمرًا محفوفًا بالمخاطر - وليس حقيقة أن المشروع سيعمل كما كان من قبل ، وسيستغرق الكثير من الوقت.
في المجموع ، يمكن تمييز ثلاث مراحل من تنفيذ GraphQL:
- خلق العملاء
- إنشاء مُهيئ لنموذج Legacy ؛
- استبدال طلبات API بـ GraphQL.
GraphQLClient
كما هو الحال مع أي عميل ، يجب أن يكون لدى GraphQLClient طريقة جلب ، وبعد ذلك سيتم تحميل البيانات التي نحتاجها.
في رأيي ، يجب أن تأخذ طريقة جلب GraphQLClient عددًا ، بناءً على تنفيذ الطلب المقابل. سيتيح لنا هذا النهج تلقي البيانات بسهولة للكيان المطلوب أو حتى الشاشة. إذا قبل الطلب المعلمات ، فسيتم تمريرها كقيم مرتبطة. مع هذا النهج ، من الأسهل استخدام GraphQL وإنشاء استعلامات مرنة.
enum GraphQLRequest { case image(ImageId?) }
يجب أن يحتوي عميل GraphQL المخصص لدينا على ApolloClient المخصص للميزات الحالية ، وكذلك طريقة تحميل الجلب المذكورة أعلاه.
func fetch<Response>(requestType: GraphQLRequest, completion: @escaping (QLRequestResult<Response>) -> Void)
ما هو QLRequestResult؟ انها عادية
typealias QLRequestResult<Response> = Result<Response, APIError>
تتيح لك طريقة الجلب الوصول إلى العميل من خلال البروتوكول وإجراء التبديل على requestType. بناءً على requestType ، يمكنك استخدام طريقة التحميل الخاصة المقابلة ، حيث يمكنك تحويل النموذج الناتج إلى الطراز القديم. على سبيل المثال:
private func fetchGameInfo<Response>(gameId: String? = "", completion: @escaping (QLRequestResult<Response>) -> Void) {
نتيجة لذلك ، حصلنا على نموذج قديم جاهز تم الحصول عليه من GraphQL.
نوع العددية
في وثائق GraphQL ، يوصف نوع العدد على النحو التالي: "نوع العدد هو معرف فريد يستخدم غالبًا لإعادة تحديد كائن أو كمفتاح لذاكرة التخزين المؤقت." بالنسبة لـ swift ، يمكن بسهولة ربط نوع العدد مع typealias.
عند كتابة عميل ، واجهت مشكلة في خططي كان هناك نوع طويل ، والذي كان في الأساس
typealias Long = Int64
سيكون كل شيء على ما يرام ، لكن Apollo يرسل تلقائيًا جميع أدوات تسجيل المستخدم إلى سلسلة ، والتي تسبب تعطلًا. لقد حلت المشكلة مثل هذا:
في المستقبل ، لكل نوع قياسي ، تحتاج إلى إضافة typealias جديد. مع الإصدار 14.0 من Apollo ، أضافوا "دعمًا لقواعد مخصصة Int." إذا كنت تريد تجنب استخدام هذا النهج والعلم في codegen ، ثم تحقق من حل هذه المشكلة في
بوابة Apollo .
إيجابيات وسلبيات
لماذا هذا النهج جيد؟ انتقال سريع إلى حد ما إلى استخدام GraphQL ، فيما يتعلق بالنهج مع إزالة جميع النماذج القديمة.
في المستقبل ، عندما نحتاج إلى الحصول على بيانات لأي شاشة / نموذج ، يمكننا الانتقال إلى GraphQLClient والحصول على البيانات اللازمة.
من السلبيات:
- تحويل نوع النموذج في العميل ، يمكن للمرء أن نقل إلى كيان آخر منذ ذلك الحين العمل مع البيانات ليست مسؤولية العميل.
- مترامية الاطراف GraphQLClient. بعد إضافة استفسارات جديدة ، سوف ينمو صفنا بشكل أكبر وأكبر. أحد الحلول هو الامتدادات التي سيتم وصف طرق التحميل بها ، والتي تحدثت عنها في فصل GraphQLClient.
النتائج
بشكل عام ، يمكن أن يكون التبديل إلى GraphQL سريعًا وغير مؤلم مع عميل مكتوب جيدًا. استغرق الأمر مني حوالي ثلاثة أيام = 24 ساعة عمل. خلال هذا الوقت ، تمكنت من إنشاء عميل وترجمة النموذج وإعادة إنشاء نموذج GameInfo. النهج الموصوف ليس حلا سحريا ، ولكن قراري بحت ، نفذ في وقت قصير.
إذا كان لديك معلم GraphQL بينك ، أقترح عليك مشاركة تجربتك وإخبار مدى ملاءمة استخدام GraphQL + Apollo في المشروعات الكبيرة. أم أن اللعبة لا تستحق كل هذا العناء؟
شكرا لاهتمامكم!