الإعداد والملفّات الشخصية وActuator

العمل مع YAML

18 دقيقة الدرس 4 من 13

العمل مع YAML

يدعم Spring Boot تنسيقَي ملفات الضبط دون أي إعداد إضافي: الكلاسيكي application.properties (أزواج مفتاح=قيمة) والأكثر تعبيريةً application.yml (YAML). يُحمَّل كلا الملفَّين تلقائيًا من جذر مسار الفئات — لا تحتاج إلى تبعية إضافية أو تعليق توضيحي للتبديل بينهما. إنّ فهم بنية YAML والموازنة بين التنسيقَين مهارة جوهرية لأي مطوّر Spring Boot محترف.

أساسيات YAML في أقل من خمس دقائق

YAML (اختصار YAML Ain't Markup Language) يمثّل البيانات على هيئة أزواج مفتاح-قيمة مسنّنة وقوائم وخرائط. يتوفّر دعم YAML في Spring عبر مكتبة SnakeYAML الموجودة بالفعل في مسار الفئات عند تضمين spring-boot-starter.

القواعد الأساسية التي تحتاج إلى معرفتها:

  • الإزاحة تُحدّد التداخل. استخدم المسافات دائمًا، وليس علامات التبويب. مسافتان لكل مستوى هي الاتفاقية المعتمدة عالميًا في مشاريع Spring.
  • يُفصل المفتاح عن القيمة بنقطتَين يتبعهما مسافة (: ).
  • القوائم تستخدم شرطة بادئة (- ).
  • السلاسل النصية يمكن أن تكون بدون تنصيص ما لم تحتوِ على محارف خاصة (: { } [ ] , # & * ? | > ' " % @ `).
  • القيم المنطقية هي true / false (بحروف صغيرة).
YAML مجموعة شاملة من JSON. أي مستند JSON صالح هو أيضًا YAML صالح، لكن العكس ليس صحيحًا. من الناحية العملية ستكتب دائمًا YAML بأسلوب الكتلة المسنّنة لا بأسلوب JSON.

Properties المسطّحة مقابل YAML المتداخلة — مقارنة جنبًا إلى جنب

لنأخذ ضبطًا نموذجيًا لقاعدة البيانات والخادم. في application.properties كل مفتاح مؤهَّل بالكامل:

server.port=8080 server.servlet.context-path=/api spring.datasource.url=jdbc:postgresql://localhost:5432/inventory spring.datasource.username=appuser spring.datasource.password=secret spring.datasource.hikari.maximum-pool-size=10 spring.jpa.show-sql=false spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

الضبط نفسه تمامًا في application.yml:

server: port: 8080 servlet: context-path: /api spring: datasource: url: jdbc:postgresql://localhost:5432/inventory username: appuser password: secret hikari: maximum-pool-size: 10 jpa: show-sql: false properties: hibernate: dialect: org.hibernate.dialect.PostgreSQLDialect

يُسطّح كلٌّ من PropertySourcesPlaceholderConfigurer وتجريد Environment في Spring ملف YAML إلى مفاتيح النقطة الداخلية نفسها، لذا تعمل @Value("${server.port}") و@ConfigurationProperties(prefix = "spring.datasource") بشكل متطابق بغضّ النظر عن تنسيق الملف الذي اخترته.

القوائم في YAML

في ملفات properties تستخدم القوائم مفاتيح مفهرسة: app.allowed-origins[0]=https://example.com. في YAML تُقرأ القائمة نفسها بشكل طبيعي:

app: allowed-origins: - https://example.com - https://staging.example.com - http://localhost:3000 # الأسلوب المضمَّن (التدفق) — مكافئ ومفيد للقوائم القصيرة roles: - ADMIN - USER - VIEWER

عند الربط بكائن @ConfigurationProperties، يُعيّن Spring قائمة YAML مباشرةً إلى حقل من نوع List<String>.

ملفات YAML متعددة المستندات

يمكن أن يحتوي ملف application.yml الواحد على عدة مستندات مفصولة بـ ---. يمكن تفعيل كل مستند عند تنشيط ملف تعريف بعينه:

# الضبط الافتراضي / الأساسي spring: datasource: url: jdbc:h2:mem:devdb username: sa password: "" jpa: show-sql: true --- spring: config: activate: on-profile: production datasource: url: jdbc:postgresql://prod-db:5432/inventory username: ${DB_USER} password: ${DB_PASS} jpa: show-sql: false

يوفّر المستند الأول القيم الافتراضية لجميع البيئات. أما المستند الثاني فيُلغي فقط مفاتيح مصدر البيانات و JPA عند تنشيط ملف تعريف production. هذه إحدى أبرز مزايا YAML: يمكنك دمج ما كان سيكون ثلاثة ملفات منفصلة (application.properties وapplication-dev.properties وapplication-prod.properties) في ملف واحد مقروء.

فضّل الملفات المنفصلة لكل ملف تعريف على YAML متعدد المستندات في التطبيقات الكبيرة. الدمج مريح للمشاريع الصغيرة، لكن ملف YAML يبلغ 300 سطر وفيه خمسة مستندات لملفات تعريف يصعب مراجعته في طلبات السحب. نمط application-{profile}.yml (ملف واحد لكل ملف تعريف) يتوسّع بشكل أفضل ويُبقي الملفات التي تحتوي على أسرار معزولة.

مراسي YAML والأسماء البديلة — تقليل التكرار

يدعم YAML المراسي (&name) والأسماء البديلة (*name) التي تتيح لك إعادة استخدام كتلة دون تكرارها. هذه ميزة خاصة بـ YAML لا يوجد لها مكافئ في ملفات properties:

# تعريف كتلة قابلة لإعادة الاستخدام مرة واحدة logging-defaults: &logging-defaults level: root: INFO org.springframework: WARN com.example: DEBUG --- spring: config: activate: on-profile: staging logging: <<: *logging-defaults # دمج جميع المفاتيح من المرساة file: name: /var/log/app-staging.log --- spring: config: activate: on-profile: production logging: <<: *logging-defaults file: name: /var/log/app-prod.log
لا يدعم Spring Boot مفاتيح دمج YAML (<<:) بشكل كامل في جميع السياقات. تحلّ SnakeYAML المراسي قبل تسليم البيانات إلى رابط Spring، لذا تعمل مراسي القيم البسيطة بشكل موثوق. أما مفاتيح الدمج (<<:) فتعمل لضبط التسجيل والخصائص المخصصة، لكن تجنّب استخدامها داخل كتل spring.* أو server.* — إذ قد يُفسّر ربط Spring المرن الخرائط المدمجة بشكل خاطئ أحيانًا. اختبر بدقة إن استخدمت هذه الميزة للضبط الحيوي.

متى تفضّل YAML على Properties

لا يتفوّق أي تنسيق على الآخر بشكل مطلق — الاختيار مسألة ملاءمة:

  • اختر YAML عندما يكون لديك ضبط متداخل بعمق (مثل Spring Security أو تعريفات مسارات Spring Cloud Gateway أو ضبط Hikari المعقد)، أو عندما يقرأ فريقك YAML بطلاقة من Kubernetes أو Docker Compose، أو عندما تريد دمج ملفات التعريف متعددة المستندات في ملف واحد.
  • اختر Properties عندما يكون الضبط بسيطًا وقليلًا، أو عندما ستُعالج الملف أدوات خارجية تحلّل مفتاح=قيمة (بعض خطوط CI/CD القديمة)، أو عندما يكون أعضاء الفريق غير مألوفين بحساسية مسافات YAML.
  • لا تخلط بين التنسيقَين في التطبيق نفسه أبدًا. إذا وُجد كلٌّ من application.yml وapplication.properties، يُحمّل Spring Boot كليهما لكن application.properties يفوز عند التعارض — قاعدة أولوية صامتة مُربِكة تُسبّب أخطاء يصعب تشخيصها.

أبرز مزالق YAML

يخفي مرونة YAML عدة فخاخ تلدغ المطوّر مرة واحدة ولا يُنساها:

  • التبويب مقابل المسافات: محرف Tab في YAML يُسبّب خطأ في التحليل. اضبط محرّرك لتوسيع علامات التبويب إلى مسافات في ملفات .yml.
  • مشكلة النرويج: تُحلَّل NO المجرّدة كـ false في YAML 1.1 القديمة (التي تستخدمها SnakeYAML). انصّص رموز الدول دائمًا: country: "NO". كذلك الحال مع on وoff وyes وno.
  • النقطتان في القيم: url: http://localhost:8080 صالحة لأن ثمة مسافة بعد النقطتين. لكن message: Hello: World يُعطل التحليل — انصّصها: message: "Hello: World".
  • المسافة المفقودة بعد النقطتين: يُعامَل port:8080 كمفتاح نصي بقيمة null، وليس كـ port = 8080.

الخلاصة

يمنح YAML وضوحًا هرميًا لضبط Spring Boot. يُزيل تنسيق الكتلة المسنّنة التكرار المُمل للبادئات المشتركة، وترتبط القوائم بشكل طبيعي، وتتيح الملفات متعددة المستندات تجميع مقاطع ملفات التعريف في مكان واحد. دعم YAML في Spring Boot لا يستلزم أي ضبط — أضف application.yml إلى src/main/resources وسيُلتقط تلقائيًا. احذر من أخطاء الإزاحة والسلاسل الشبيهة بالقيم المنطقية وفخّ علامة التبويب. في الدرس القادم ستتعلّم كيف تُبقي القيم الحساسة خارج كلا التنسيقَين باستخدام متغيرات البيئة ومديري الأسرار.