فایل YAML در نگاه اول شبیه متنی ساده با چند فاصله و خط تیره است، اما همین سادگی میتواند گمراهکننده باشد. یک فاصله اشتباه، استفاده نابجا از Tab، انتخاب نادرست علامت نقلقول یا تغییر سطح تورفتگی ممکن است ساختار داده را عوض کند یا فایل را کاملاً نامعتبر سازد. در این راهنما، YAML Syntax را از قواعد پایه تا الگوهای واقعی فایلهای تنظیمات بررسی میکنیم تا بتوانید YAML خوانا، قابل نگهداری و قابل پردازش بنویسید.
پاسخ سریع: در YAML ساختار داده عمدتاً با تورفتگی مشخص میشود. کلید و مقدار با
:جدا میشوند، اعضای فهرست معمولاً با-شروع میشوند، Tab برای تورفتگی مناسب نیست، و رشتههایی که ممکن است بهعنوان عدد، Boolean، تاریخ یا مقدار خاص تفسیر شوند بهتر است داخل نقلقول قرار بگیرند. مهمترین اصل این است که در هر سطح، تورفتگی یکنواخت و معنای داده صریح باشد.
YAML Syntax چیست و چرا تورفتگی در آن حیاتی است؟
Syntax یا نحو YAML مجموعه قواعدی است که تعیین میکند یک متن چگونه به Mapping، Sequence و Scalar تبدیل شود. برخلاف JSON که مرز ساختار را با آکولاد و براکت نشان میدهد، YAML در سبک Block از فاصلههای ابتدای خط برای نمایش والد و فرزند استفاده میکند. بنابراین تورفتگی فقط برای زیبایی نیست؛ بخشی از معنی داده است.
یک پردازشگر YAML ابتدا خطوط، نشانهها، نقلقولها و سطح تورفتگی را میخواند و سپس آنها را به یک مدل داده تبدیل میکند. اگر دو خط همسطح باشند، معمولاً عضو یک ساختار مشترکاند. اگر خطی بیشتر تورفته باشد، زیرمجموعه خط قبل محسوب میشود. همین ویژگی YAML را برای فایلهای پیکربندی خوانا میکند، اما همزمان حساسیت آن را به فاصلهها بالا میبرد.
app:
name: xdflow
debug: false
ports:
- 3000
- 3001
در مثال بالا، name، debug و ports فرزندان app هستند. دو مقدار زیر ports نیز اعضای یک فهرستاند. حذف یا افزایش نامنظم فاصله میتواند این رابطه را تغییر دهد.
سه ساختمان اصلی در YAML: Mapping، Sequence و Scalar
برای یادگیری قواعد نوشتن YAML، بهتر است همه چیز را به سه ساختمان اصلی تقسیم کنیم: Mapping برای جفتهای کلید و مقدار، Sequence برای فهرست مرتب، و Scalar برای مقدارهای منفرد مانند رشته، عدد و Boolean.
Mapping یا نگاشت کلید و مقدار
در Mapping، بعد از کلید یک دونقطه قرار میگیرد. معمولاً پس از دونقطه باید فاصله باشد. کلیدها در یک Mapping بهتر است یکتا باشند، زیرا رفتار پردازشگرها در برابر کلید تکراری یکسان نیست؛ بعضی خطا میدهند و بعضی آخرین مقدار را نگه میدارند.
database:
host: localhost
port: 5432
username: app_user
Sequence یا فهرست
در سبک Block، هر عضو فهرست با خط تیره و یک فاصله شروع میشود. عضو میتواند یک مقدار ساده، یک Mapping یا حتی فهرست دیگری باشد.
languages:
- JavaScript
- Python
- Go
Scalar یا مقدار ساده
Scalar میتواند رشته، عدد، Boolean، null یا مقدارهای دیگری باشد که Schema و نسخه پردازشگر تشخیص میدهد. دقیقاً به همین دلیل، نوشتن مقدار بدون نقلقول همیشه بیخطر نیست. مثلاً رشتهای مانند 00123 ممکن است در برخی زنجیرههای پردازش به عدد تبدیل شود و صفرهای ابتدایی خود را از دست بدهد.
قواعد تورفتگی در YAML
تورفتگی مهمترین بخش YAML Syntax است. استاندارد تعداد ثابتی مانند دو فاصله را برای همه پروژهها تحمیل نمیکند، اما هر سطح باید در همان سند یکنواخت باشد. دو فاصله رایجترین قرارداد است و خوانایی خوبی دارد.
- برای تورفتگی از Space استفاده کنید، نه Tab.
- اعضای همسطح باید دقیقاً تورفتگی یکسان داشته باشند.
- فرزند باید بیشتر از والد تورفته باشد.
- مقدار یک کلید میتواند در همان خط یا در خطوط تورفته بعدی قرار گیرد.
- تورفتگی اضافی بیدلیل، ساختار را مبهم یا نامعتبر میکند.
نمونه صحیح
server:
host: 127.0.0.1
tls:
enabled: true
port: 443
نمونه غلط
server:
host: 127.0.0.1
tls:
enabled: true
در نمونه غلط، tls سه فاصله تورفتگی دارد، در حالی که باید همسطح host باشد. برخی Parserها خطا را در همان خط گزارش میکنند و برخی در خط بعد، چون تا زمانی که ساختار بعدی خوانده نشود ناسازگاری کامل مشخص نمیشود.
کلید، دونقطه و فاصله در YAML
الگوی معمول یک جفت ساده key: value است. وجود فاصله بعد از دونقطه مرز کلید و مقدار را روشن میکند. رشتههایی که خودشان شامل دونقطه و فاصلهاند بهتر است Quote شوند تا Parser آنها را بهاشتباه Mapping جدید تلقی نکند.
title: "راهنما: YAML برای تنظیمات"
url_path: /tools/yaml-studio
time: "10:30"
دونقطه بدون فاصله در بعضی رشتهها بخشی از مقدار محسوب میشود؛ با این حال تکیه بر جزئیات ظریف Parser نگهداری را دشوار میکند. وقتی مقدار شبیه Syntax خود YAML است، نقلقول انتخاب امنتر و واضحتری است.
نحوه نوشتن فهرستها و فهرست اشیا
فهرست ساده فقط مجموعهای از مقدارهاست، اما در فایلهای واقعی معمولاً با فهرست اشیا روبهرو میشویم؛ مانند سرویسها، کاربران، مراحل Pipeline یا Ruleها. در این حالت خط تیره آغاز یک عضو جدید است و کلیدهای بعدی همان عضو با تورفتگی مناسب ادامه پیدا میکنند.
services:
- name: api
port: 8080
replicas: 3
- name: worker
port: 8081
replicas: 2
در این نمونه، services یک Sequence شامل دو Mapping است. کلیدهای port و replicas باید با name همسطح باشند. اگر یکی از آنها بیشتر تورفته شود، Parser انتظار ساختاری متفاوت خواهد داشت.
سبک Flow برای ساختارهای کوتاه
YAML علاوه بر سبک Block، سبک Flow شبیه JSON دارد. برای مقدارهای کوتاه میتوان از براکت و آکولاد استفاده کرد، اما استفاده زیاد از آن مزیت خوانایی YAML را کم میکند.
ports: [80, 443]
labels: { environment: production, region: eu-west }
رشتهها و زمان استفاده از نقلقول
رشته ساده یا Plain Scalar بدون نقلقول نوشته میشود. این روش خواناست، اما برخی نویسهها و الگوها معنی نحوی دارند. برای مقدارهای حساس، نقلقول باعث میشود قصد نویسنده روشن باشد.
| نوع نوشتن | نمونه | کاربرد |
|---|---|---|
| بدون نقلقول | name: xdflow | رشتههای ساده و بدون ابهام |
| Single Quote | pattern: 'a:b' | حفظ بیشتر نویسهها به شکل Literal |
| Double Quote | message: "line\nnext" | استفاده از Escape Sequenceها |
در Single Quote، برای قرار دادن خود علامت تکنقلقول معمولاً آن را دو بار مینویسید. در Double Quote، Escapeهایی مانند \n، \t و Unicode Escape قابل استفادهاند. برای مسیرهای ویندوز، Regex و رشتههای دارای Backslash باید با دقت انتخاب کنید؛ Single Quote معمولاً خواناتر است.
windows_path: 'C:\temp\logs'
regex: '^user_[0-9]+$'
multiline_hint: "first\nsecond"
کامنت در YAML
کامنت با # شروع میشود و تا پایان خط ادامه دارد. کامنتها بخشی از مدل داده نیستند و بسیاری از Parserها پس از خواندن و دوباره Serialize کردن فایل، آنها را حفظ نمیکنند. بنابراین برای ویرایش خودکار فایلهای YAML باید از کتابخانهای استفاده شود که حفظ Comment و ترتیب را پشتیبانی کند.
# تنظیمات محیط production
environment: production
replicas: 3 # تعداد نمونههای سرویس
اگر علامت # بخشی از مقدار است، مقدار را Quote کنید؛ بهخصوص وقتی قبل از آن فاصله وجود دارد.
Boolean و null؛ نقطهای که نسخه و Parser اهمیت پیدا میکند
در YAML 1.2، شکلهای استاندارد و روشن Boolean معمولاً true و false هستند. بعضی Parserهای قدیمیتر یا تنظیمشده با قواعد YAML 1.1 ممکن است واژههایی مانند yes، no، on و off را Boolean تشخیص دهند. برای جلوگیری از رفتار متفاوت بین محیطها، از true و false استفاده کنید و واژههای متنی مشابه را Quote کنید.
feature_enabled: true
answer_text: "yes"
power_mode: "off"
optional_value: null
empty_value: ~
null و ~ میتوانند مقدار تهی را نشان دهند، اما استفاده صریح از null برای بیشتر تیمها خواناتر است. کلیدی که بدون مقدار نوشته میشود نیز ممکن است null تفسیر شود، ولی این سبک میتواند با مقدار جاافتاده اشتباه گرفته شود.
عددها، تاریخها و رشتههای شبیه مقدار خاص
عدد صحیح و اعشاری را میتوان بدون Quote نوشت. با این حال شناسهها، شماره تلفن، کد پستی، نسخه نرمافزار و مقادیر دارای صفر ابتدایی از نظر معنایی عدد نیستند و باید رشته باقی بمانند.
replicas: 3
ratio: 0.75
postal_code: "00123"
version: "1.20"
release_date: "2026-08-07"
Quote کردن تاریخ زمانی مهم است که برنامه شما دقیقاً رشته میخواهد. برخی Parserها یا Frameworkها ممکن است مقدار شبیه تاریخ را به نوع Date/Time تبدیل کنند. همچنین اعداد بسیار بزرگ ممکن است در زبان مقصد به نوعی با محدودیت دقت منتقل شوند؛ نوع داده را بعد از Parse در برنامه بررسی کنید.
رشته چندخطی با | و >
YAML برای متنهای چندخطی دو سبک اصلی دارد. علامت | شکست خطها را حفظ میکند و برای اسکریپت، متن قالبدار یا کلید خصوصی مناسبتر است. علامت > بیشتر شکست خطهای معمول را به فاصله تبدیل میکند و برای پاراگرافهای بلند مناسب است.
script: |
npm ci
npm run test
npm run build
description: >
این متن در چند خط نوشته شده است
اما معمولاً بهصورت یک پاراگراف خوانده میشود.
تورفتگی خطوط بعد از | یا > تعیین میکند کدام خطوط جزو متناند. همچنین Chomping Indicatorهایی مانند |- و |+ نحوه نگهداری خط خالی انتهایی را کنترل میکنند. - خط انتهایی را حذف میکند و + خطوط خالی انتهایی را نگه میدارد.
command: |-
echo "start"
echo "done"
Anchor، Alias و Merge در YAML Syntax
Anchor با & یک Node را نامگذاری میکند و Alias با * به آن ارجاع میدهد. این قابلیت تکرار را کم میکند، اما پشتیبانی از Merge Key با << و جزئیات آن میتواند به Parser یا ابزار وابسته باشد. برای فایلهایی که باید میان سامانههای متعدد جابهجا شوند، سازگاری را آزمایش کنید.
defaults: &defaults
timeout: 30
retries: 3
production:
<<: *defaults
retries: 5
Alias به معنی کپی متنی ساده نیست؛ در مدل داده ممکن است به همان Node اشاره کند. در برنامههایی که داده را تغییر میدهند، این تفاوت میتواند مهم باشد. همچنین استفاده بیشازحد از Anchor فایل را برای خواننده دشوار میکند.
Document Marker و چند سند در یک فایل
سه خط تیره --- شروع سند را مشخص میکند و سه نقطه ... میتواند پایان سند را نشان دهد. یک فایل YAML میتواند چند سند داشته باشد، ولی همه ابزارها چنین فایلی را بهصورت یکسان مصرف نمیکنند. برخی APIها فقط یک سند انتظار دارند.
---
name: first
---
name: second
...
قبل از استفاده از Multi-document YAML، قرارداد مصرفکننده را بررسی کنید. در غیر این صورت ممکن است فقط سند اول خوانده شود یا کل فایل رد شود.
مثال واقعی: فایل تنظیمات یک سرویس
مثال زیر چند قاعده را همزمان نشان میدهد: Mapping تودرتو، فهرست اشیا، Boolean صریح، رشته Quoteشده، متن چندخطی و مقدارهای عددی.
application:
name: xdflow-api
environment: production
base_url: "api.internal:8443"
server:
host: 0.0.0.0
port: 8443
tls_enabled: true
logging:
level: info
outputs:
- console
- file
file:
path: "/var/log/xdflow/api.log"
max_size_mb: 100
workers:
- name: article-import
concurrency: 2
enabled: true
- name: tool-jobs
concurrency: 4
enabled: true
notice: >
این تنظیمات برای محیط production است و تغییر آن
باید پس از بررسی و اجرای تست انجام شود.
این فایل از نظر Syntax میتواند معتبر باشد، اما معتبر بودن نحوی تضمین نمیکند که برنامه تمام کلیدها و مقادیر را قبول کند. برای مثال، ممکن است برنامه فقط سطحهای خاص Logging یا محدوده مشخصی برای Concurrency داشته باشد. این مرحله Validation معنایی یا Schema Validation است و با Parse موفق فرق دارد.
تفاوت YAML معتبر با تنظیمات معتبر برای برنامه
| مرحله | پرسش اصلی | نمونه خطا |
|---|---|---|
| Syntax Validation | آیا متن طبق قواعد YAML قابل Parse است؟ | تورفتگی ناسازگار یا نقلقول بستهنشده |
| Type/Schema Validation | آیا شکل و نوع داده مطابق قرارداد است؟ | port رشته است ولی عدد لازم است |
| Semantic Validation | آیا مقدار در منطق برنامه معنی دارد؟ | پورت خارج از محدوده یا نام محیط ناشناخته |
| Security Review | آیا مصرف فایل امن است؟ | استفاده از Loader ناامن یا داده محرمانه در فایل |
ابزار Formatter ممکن است فایل را مرتب و خوانا کند، اما جای Validator یا Schema را نمیگیرد. از طرف دیگر، Parser صرفاً داده را میخواند و لزوماً سیاستهای امنیتی و قواعد کسبوکار را بررسی نمیکند.
خطاهای رایج YAML و روش عیبیابی
استفاده از Tab
Tab را با Space جایگزین کنید و نمایش نویسههای نامرئی را در ویرایشگر فعال کنید. ترکیب Tab و Space یکی از سختترین خطاها برای تشخیص بصری است.
تورفتگی نامنظم
از بالاترین والد شروع کنید و سطح هر خط را بشمارید. بلوک مشکوک را موقتاً کوچک کنید تا کمترین نمونه خطادار به دست آید.
جا افتادن فاصله بعد از دونقطه
عبارت key:value ممکن است بهعنوان یک رشته یا ساختار ناخواسته خوانده شود. برای Mapping استاندارد از key: value استفاده کنید.
رشته دارای # یا : بدون Quote
وقتی مقدار شامل نشانههای نحوی است، آن را Quote کنید. این کار مخصوصاً برای URL داخلی، زمان، پیام و الگوها مفید است.
کلید تکراری
به خروجی Parser اعتماد نکنید؛ کلید تکراری را خطا در نظر بگیرید. نگه داشتن آخرین مقدار میتواند پیکربندی امنیتی یا عملیاتی را بیصدا تغییر دهد.
خطا در خط بعد از محل واقعی مشکل
Parser ممکن است خطی را گزارش کند که فقط ناسازگاری در آن آشکار شده است. چند خط قبل را نیز بررسی کنید، بهخصوص نقلقول باز، براکت بستهنشده و تورفتگی والد.
نکات امنیتی هنگام Parse کردن YAML
YAML فقط یک قالب متنی نیست؛ برخی پیادهسازیها قابلیت ساخت نوعهای خاص یا Objectهای زبان میزبان را نیز ارائه میکنند. هنگام خواندن YAML غیرقابل اعتماد، از حالت Safe Load یا معادل امن کتابخانه استفاده کنید و اجازه ساخت نوعهای دلخواه را ندهید. نام دقیق API به زبان و کتابخانه وابسته است.
- YAML دریافتی از کاربر را با Loader امن Parse کنید.
- حجم فایل، عمق Nesting و تعداد Aliasها را محدود کنید.
- Secretها مانند Token، Password و Private Key را در فایل عمومی یا Repository قرار ندهید.
- پس از Parse، Schema و محدوده مقدارها را Validate کنید.
- برای فایلهای عملیاتی، تغییرات را Review و در محیط جداگانه آزمایش کنید.
Aliasهای بسیار زیاد یا ساختارهای عمیق میتوانند مصرف حافظه و زمان پردازش را بالا ببرند. کنترل منابع بخشی از امنیت Parser است، نه صرفاً بهینهسازی عملکرد.
بهترین روشها برای نوشتن YAML قابل نگهداری
- در کل پروژه دو فاصله را بهعنوان قرارداد تورفتگی انتخاب کنید.
- Boolean را فقط با
trueوfalseبنویسید. - شناسهها، نسخهها، تاریخها و مقدارهای دارای صفر ابتدایی را Quote کنید.
- از کلیدهای تکراری جلوگیری کنید و Lint را در CI اجرا کنید.
- برای متن چندخطی آگاهانه بین
|و>انتخاب کنید. - Anchor را فقط وقتی استفاده کنید که تکرار واقعی را کم میکند.
- ساختارهای بسیار تودرتو را به چند بخش منطقی تقسیم کنید.
- Syntax Validation را از Schema Validation جدا بدانید.
- نسخه YAML و رفتار Parser اصلی پروژه را مستند کنید.
- قبل از انتشار، فایل را با همان Runtime مصرفکننده آزمایش کنید.
چکلیست سریع بررسی YAML Syntax
- آیا فقط Space برای تورفتگی استفاده شده است؟
- آیا تمام اعضای همسطح تورفتگی یکسان دارند؟
- آیا بعد از دونقطه Mapping فاصله وجود دارد؟
- آیا هر عضو فهرست با خط تیره و فاصله شروع میشود؟
- آیا رشتههای مبهم Quote شدهاند؟
- آیا کلید تکراری وجود ندارد؟
- آیا متنهای چندخطی تورفتگی درست دارند؟
- آیا Booleanها صریحاند؟
- آیا فایل با Parser واقعی پروژه تست شده است؟
- آیا Validation ساختاری و معنایی نیز انجام شده است؟
جمعبندی
YAML Syntax بر خوانایی و تورفتگی تکیه دارد. Mapping با کلید و دونقطه، Sequence با خط تیره و Scalar با مقدارهای ساده ساخته میشود. برای نوشتن YAML معتبر، تورفتگی یکنواخت، استفاده نکردن از Tab، Quote کردن مقدارهای مبهم و تفکیک اعتبار نحوی از Schema Validation ضروری است. در فایلهای حساس، Loader امن، محدودیت منابع و بررسی نوع و محدوده مقدارها را نیز جدی بگیرید. برای مشاهده ساختار، فرمت و بررسی سریع فایل میتوانید از ابزار داخلی YAML Studio استفاده کنید.