من الجيد أن إطار عمل مثل SpringBoot يمكنه فعل أشياء كثيرة لك.
تحتاج فقط إلى فئة كيان JPA بالإضافة إلى واجهة مستودع بسيطة ويمنحك SpringData كل ما تحتاجه لعمليات قاعدة بيانات CRUD النموذجية.
أنت تكتب فئة تحكم REST بسيطة ولديك REST API قيد التشغيل، أليس كذلك؟
مرحبًا، لكنك نسيت كتابة DTO! ولكن لماذا تحتاج إليها بالفعل بينما يمكن أن يعمل تطبيقك بدونها؟
هناك بالتأكيد بعض الأسباب العامة:
ولكن يمكن أن تحدث أشياء غريبة أخرى أيضًا. سأعرض لك مثالًا غريبًا بناءً على تجربتي.
يحتوي مستودع GitHub هذا على تطبيق بسيط يعمل بدون DTOs. يوجد كيان مستخدم، يمكن لكل مستخدم أن يكون لديه معاملات متعددة. لدينا أيضًا وحدة خدمة بين المستودع وRestController، لالتقاط استثناءات الوصول إلى قاعدة البيانات المحتملة.
نظرًا لأننا نريد إنشاء تطبيق جاهز للإنتاج، فإننا لا نريد أن يقوم Hibernate بإنشاء DDL. بدلاً من ذلك، لدينا schema.sql الذي ينشئ الجداول (قد نتحول لاحقًا إلى Flyway أو Liquibase). بالنسبة لمثالنا البسيط، لدينا أيضًا data.sql بحيث لا تكون جداولنا فارغة.
عندما نقوم بتشغيل التطبيق واستدعاء نقطة نهاية API على http://localhost:8080/users، نحصل على JSON المتوقع الذي يحتوي على المستخدمين ومعاملاتهم.
الآن دعونا ننتبه إلى سطرين من التعليمات البرمجية في فئة المعاملات، مع وضع علامة //!!
@JsonIgnore //!!
الرائحة الأولى هي أنه في فئة المعاملات كان علينا إضافة التعليق التوضيحي @JsonIgnore إلى مرجع المستخدم. بدون هذا التعليق التوضيحي، يتعطل تسلسل JSON بسبب التكرار اللانهائي.
لنتخيل الآن أن شخصًا ما ارتكب خطأً بإضافة حقل آخر (وصف) إلى كيان المعاملة، لكنه نسي ضبط عبارات SQL (أو قام بتشغيل التطبيق في بيئة لم يتم تطبيق تغيير المخطط فيها).
]
وصف السلسلة الخاصة؛//!!
بالطبع، الآن فشل استدعاء API. لكن انظر إلى معالجة الأخطاء! جملة الالتقاط داخل UserService لا تعمل كما هو متوقع. بدلاً من ذلك يمكننا رؤية تتبع مكدس غريب في السجل:
GlobalExceptionHandler: خطأ غير متوقع org.springframework.http.converter.HttpMessageNotWritableException: تعذر كتابة JSON:
لقد رأيت هذا الموقف ذات مرة (من الواضح، مع تطبيق أكبر بكثير من هذا المثال) واستغرق الأمر بعض الوقت لفهم سبب هروب استثناء SQL من الخدمة ولماذا كنت أحصل على HttpMessageNotWritableException. هل تستطيع ان تراه؟
ما يحدث هو أن فئة UserService (عبر UserRepository) تستعلم فقط عن جدول قاعدة بيانات USERS. لا تعد كيانات المعاملة جزءًا من النتيجة بسبب التحميل البطيء للإسبات الافتراضي. فقط عندما يحاول برنامج إلغاء تسلسل Jackson إنشاء JSON من مثيل المستخدم، فإنه يستدعي طريقة getTransactions الخاصة به والتي تجعل Hibernate يجلب كيانات المعاملة.
لهذا السبب حصلنا على تتبع مكدس غريب يجمع بين عناصر JSON وSQL. تم اكتشاف الاستثناء بواسطة GlobalExceptionHandler الذي لا يعرف ما يجب فعله به، ولهذا السبب تظهر رسالة السجل "خطأ غير متوقع".
آمل أن يجعلك هذا التمرين الصغير تفهم بشكل أعمق مدى خطورة السماح باختلاط طبقات مختلفة من تطبيقك. إن مجرد رؤية سيناريوهات "اليوم المشمس" لتطبيقك بينما لا يزال صغيرًا قد يدفع بعض المطورين إلى الاستمرار في فعل الشيء الخطأ حتى فوات الأوان.
ليس عليك كتابة الكود المعياري لتعيين الحقول بين DTO الخاص بك والطبقات الأخرى لتطبيقك. بإمكان MapStruct القيام بذلك نيابةً عنك.
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3