تفاصيل المشكلة وفق RFC 7807 واستجابات الأخطاء المتسقة
أعِد حمولات أخطاء منظمة متوافقة مع RFC 7807 باستخدام ProblemDetail في Spring 6
تفاصيل المشكلة وفق RFC 7807 واستجابات الأخطاء المتسقة درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.
ما هو RFC 7807؟
يحدد RFC 7807، المعروف باسم «Problem Details for HTTP APIs»، تنسيق JSON قياسيًا لاستجابات الأخطاء. فهو يلغي الحاجة إلى تنسيقات أخطاء مخصصة لكل API، ويمنح العملاء بنية متوقعة لتحليلها.
حقول RFC 7807
الحقول القياسية هي: type (URI يحدد المشكلة)، وtitle (ملخص قابل للقراءة البشرية)، وstatus (رمز حالة HTTP)، وdetail (شرح محدد)، وinstance (URI للحالة المحددة).
{
"type": "https://api.example.com/errors/not-found",
"title": "Resource Not Found",
"status": 404,
"detail": "User with id 42 does not exist.",
"instance": "/api/users/42"
}ProblemDetail في Spring 6
يوفر Spring 6 وSpring Boot 3 دعمًا مدمجًا لـ ProblemDetail. أعد ProblemDetail من معالجات الاستثناءات، أو استخدم ErrorResponseException.
import org.springframework.http.ProblemDetail;
@ExceptionHandler(ResourceNotFoundException.class)
public ProblemDetail handleNotFound(ResourceNotFoundException ex, HttpServletRequest req) {
ProblemDetail pd = ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage());
pd.setType(URI.create("https://api.example.com/errors/not-found"));
pd.setTitle("Resource Not Found");
pd.setInstance(URI.create(req.getRequestURI()));
return pd;
}إضافة امتدادات مخصصة
يدعم ProblemDetail خصائص التوسعة عبر setProperty(key, value) لإضافة تفاصيل خاصة بالمجال، مثل رموز الأخطاء أو أخطاء الحقول.
ProblemDetail pd = ProblemDetail.forStatus(HttpStatus.BAD_REQUEST);
pd.setTitle("Validation Failed");
pd.setProperty("errors", fieldErrors); // custom extension
pd.setProperty("timestamp", Instant.now());تفعيل RFC 7807 في Spring MVC
فعّل ProblemDetail لجميع استثناءات Spring المدمجة بضبط spring.mvc.problemdetails.enabled=true في application.properties. عندها يغلّف Spring الاستثناءات القياسية، مثل 404 و405، تلقائيًا بتنسيق RFC 7807.
# application.properties:
spring.mvc.problemdetails.enabled=trueErrorResponseException
اطرح ErrorResponseException من كود الخدمة لإنشاء استجابة RFC 7807 من دون طريقة معالج؛ إذ يلتقطها Spring MVC وينسقها.
throw new ErrorResponseException(HttpStatus.CONFLICT,
ProblemDetail.forStatusAndDetail(HttpStatus.CONFLICT,
"Email already exists: " + email), null);فئة فرعية مخصصة من ProblemDetail
أنشئ فئة فرعية خاصة بالمجال من ProblemDetail لإضافة حقول توسعة ذات أنواع محددة والحفاظ على نظافة كود المعالج.
public class ValidationProblemDetail extends ProblemDetail {
private final Map<String, String> fieldErrors;
public ValidationProblemDetail(Map<String, String> errors) {
super(HttpStatus.BAD_REQUEST.value());
this.fieldErrors = errors;
setTitle("Validation Failed");
setProperty("fieldErrors", errors);
}
}نوع المحتوى: application/problem+json
ينبغي أن تستخدم استجابات RFC 7807 نوع المحتوى application/problem+json حتى يتمكن العملاء من تمييز استجابات المشكلات عن حمولات JSON العادية.
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.contentType(MediaType.APPLICATION_PROBLEM_JSON)
.body(pd);قائمة التحقق من بنية الأخطاء المتسقة
تتضمن واجهة الأخطاء الجيدة: (1) عنوان URI لنوع قابل للقراءة آليًا، (2) عنوانًا قابلًا للقراءة البشرية، (3) رمز حالة HTTP دقيقًا، (4) رسالة تفصيلية محددة، (5) عنوان URI لمثيل الطلب، (6) حقول توسعة اختيارية مثل الطابع الزمني وtraceId وأخطاء الحقول.
معرّفات التتبّع لقابلية المراقبة
أضف معرّف التتبّع الخاص بالطلب (من Micrometer Tracing أو MDC) إلى خاصية توسعة، حتى يتمكن المهندسون من ربط سجلات الأخطاء بالطلب المحدد الذي فشل.
pd.setProperty("traceId", MDC.get("traceId"));
pd.setProperty("timestamp", Instant.now());اختبار تفاصيل المشكلات
في اختبارات @WebMvcTest، تحقّق من أن نوع محتوى الاستجابة هو application/problem+json، وأن حقول JSON مثل status وtitle وdetail تطابق القيم المتوقعة.
mockMvc.perform(get("/api/users/999"))
.andExpect(status().isNotFound())
.andExpect(content().contentType("application/problem+json"))
.andExpect(jsonPath("$.status").value(404))
.andExpect(jsonPath("$.title").value("Resource Not Found"));تحقق سريع
ما خاصية Spring Boot التي تفعّل RFC 7807 لاستثناءات Spring MVC المدمجة؟
مراجعة
يوحّد RFC 7807 استجابات أخطاء JSON باستخدام حقول type وtitle وstatus وdetail وinstance. يوفر Spring 6 كلاً من ProblemDetail وErrorResponseException. فعّله باستخدام spring.mvc.problemdetails.enabled=true. أضف traceId والطابع الزمني كامتدادات لتحسين قابلية المراقبة.
الأسئلة الشائعة
هل درس «تفاصيل المشكلة وفق RFC 7807 واستجابات الأخطاء المتسقة» مجاني؟
نعم — نص درس «تفاصيل المشكلة وفق RFC 7807 واستجابات الأخطاء المتسقة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.
ماذا ستتعلم في «تفاصيل المشكلة وفق RFC 7807 واستجابات الأخطاء المتسقة»؟
أعِد حمولات أخطاء منظمة متوافقة مع RFC 7807 باستخدام ProblemDetail في Spring 6 تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟
لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «تفاصيل المشكلة وفق RFC 7807 واستجابات الأخطاء المتسقة»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟
نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- التحقق من صحة الـ beans: @NotNull و@Size و@Pattern
- تعليقات القيود المخصصة
- معالجة الاستثناءات العامة باستخدام @ControllerAdvice
- تفاصيل المشكلة وفق RFC 7807 واستجابات الأخطاء المتسقة