هر پیامی که بین دو سرویس رد میشود — روی HTTP یا Kafka — باید به بایت تبدیل و برگردد. انتخاب فرمت و مدیریت تکامل آن، تفاوت سیستمی است که نسخه جدیدش بدون ترس دیپلوی میشود با سیستمی که هر تغییر کوچک، consumer هایش را میشکند.
| فرمت | حجم/سرعت | Schema | بهترین جا |
|---|---|---|---|
| JSON | متنی، بزرگ، کند | ندارد (یا JSON Schema جدا) | API های عمومی، دیباگ، انعطاف |
| Protobuf | باینری فشرده، سریع | الزامی (.proto) با شماره فیلد | سرویس-به-سرویس داخلی، gRPC |
| Avro | باینری، schema همراه/مرجع | الزامی، evolution قوی | رویدادهای Kafka در مقیاس |
| MessagePack | باینریِ JSON-مانند | ندارد | جایگزین سریع JSON بدون schema |
سازگاری: قانون مهمتر از فرمت
Backward compatible
کد جدید بتواند داده نوشتهشده با schema قدیم را بخواند — مثلاً افزودن فیلد اختیاری با مقدار پیشفرض.
Forward compatible
کد قدیمی بتواند داده نسخه جدید را بخواند (فیلد ناشناخته را نادیده بگیرد).
Full
هر دو جهت؛ استاندارد طلایی برای رویدادهای Kafka که consumer ها با نسخههای مختلف زندهاند.
- قواعد امن: فقط فیلد اختیاری با default اضافه کن؛ هرگز فیلد را حذف یا rename نکن؛ نوع فیلد را عوض نکن؛ در Protobuf شماره فیلد را بازیافت نکن.
- Schema Registry (مثل Confluent) کنار Kafka میایستد: producer schema را ثبت میکند، registry سازگاری را enforce میکند، consumer با ID نسخه درست میخواند — بدون registry، topic ها به معدلفیل قراضه تبدیل میشوند.
- تغییر ناسازگار = topic جدید (مثل API v2) + مهاجرت تدریجی مصرفکنندهها.
gRPC و بقیه
- gRPC = Protobuf + HTTP/2: چهار مدل (unary ،server-streaming ،client-streaming ،bi-directional)؛ برای سرویسهای داخلی سریع و با قرارداد سفت، ولی بدون پروکسی مرورگر مستقیم کار نمیکند (gRPC-Web).
- GraphQL مسئله دیگری را حل میکند: انعطاف کلاینت روی داده — به قیمت کش پیچیده، خطر N+1 (DataLoader درس ۳۶ را ببین) و نیاز به محدودکردن عمق کوئری.
- قرارداد هرچه باشد، در CI تست سازگاری (contract test) بگذار تا شکستن قبل از دیپلوی گرفته شود (درس ۴۷).
به زبان ساده
قرارداد داده باید مثل قرارداد رسمی نسخه داشته باشد: JSON خوانا ولی سست است، Protobuf/Avro فشرده و قانونمند، و Schema Registry نگهبان سازگاری نسخههاست.
مثال واقعی
وقتی تولیدکننده پیام، فیلد price را به تومان تغییر میدهد، Schema Registry قبل از انتشار جلویش را میگیرد که مصرفکنندههای قدیمی نشکنند — مثل کنترل نسخه قرارداد بین دو شرکت.