Protobuf — این چیست، فرمت داده دودویی و اصل کار

نویسنده: IT Sectr منتشر شده: 2026-03-08 زمان مطالعه: 8 دقیقه

Protocol Buffers (Protobuf) — یک فرمت دودویی سریالی‌سازی داده‌های ساختاریافته است که توسط Google برای تبادل مؤثر اطلاعات بین خدمات طراحی شده است. این فرمت نیازمند تعریف قبلی شما در فایل‌های .proto است، که از آن‌ها کد برای زبان‌های مختلف تولید می‌شود. به گزارش مستندات رسمی Google، Protobuf اندازه پیام‌ها را 3-10 برابر کوچک‌تر از JSON تامین می‌کند. Protobuf در gRPC، Google Maps هزاران خدمت داخلی استفاده می‌شود.

نکات کلیدی

  • Protobuf — فرمت دودویی Google برای سریالی‌سازی با نمایش فشرده داده
  • شمای .proto — توصیف با نوع سختگیرانه ساختار داده با کامپایل به کد
  • عملکرد — سریالی‌سازی 3-10 برابر سریع‌تر و فشرده‌تر از JSON
  • سازگاری به عقب — تکامل شماها بدون شکستن مشتریان موجود
  • gRPC — فناوری اصلی حمل و نقل برای Protobuf در میکروسرویس‌ها

Protocol Buffers چیست؟

Protocol Buffers — یک مکانیزم سریالی‌سازی داده‌های ساختاریافته است که توسط Google طراحی شده و مشابه JSON و XML است، اما با یک تفاوت اصلی: داده‌ها به فرمت دودویی کدگذاری می‌شوند. این به آن معنی است که پیام Protobuf را نمی‌توان با چشم نیز خواند، اما به مراتب کمتر جا اشغال می‌کند و سریع‌تر از متن‌های مشابه پردازش می‌شود.

Protobuf در داخل Google برای حل مشکلات عملکرد در تبادل داده بین خدمات ایجاد شد. در سال 2008، این فناوری به یک پروژه باز مبدا با پشتیبانی از زبان‌های زیاد: C++، Java، Python، Go، JavaScript، Kotlin، Swift، Dart و سایر زبان‌ها تبدیل شد. نسخه proto3 که در سال 2016 منتشر شد، نحوه نگارش را ساده‌تر کرد و پشتیبانی از تعداد بیشتری زبان را اضافه کرد.

تفاوت کلیدی بین Protobuf و JSON — نیاز به تعریف شما قبل از شروع تبادل داده است. فایل شما (.proto) ساختار پیام را توصیف می‌کند: صحنه‌ها، انواع و شماره منحصر به فرد صحنه‌ها. از این شما، کامپایلر protoc کلاس‌هایی را در زبان مقصد برای سریالی‌سازی و از سریالی‌زدایی تولید می‌کند.

اکوسیستم Protobuf

  • gRPC — چارچوب RPC با عملکرد بالا که به صورت پیش‌فرض از Protobuf استفاده می‌کند
  • protoc — کامپایلر شمای .proto به کد در زبان‌های برنامه‌نویسی مختلف
  • Google API — اکثر API‌های عمومی Google از Protobuf استفاده می‌کنند
  • Envoy Proxy — از Protobuf برای پیکربندی و تبادل داده استفاده می‌کند

معماری Protobuf

معماری Protobuf شامل سه مؤلفه کلیدی است: زبان تعریف شما (.proto)، کامپایلر protoc و کتابخانه‌های runtime برای زبان‌های مخصوص. توسعه‌دهنده ساختار داده را در فایل .proto توصیف می‌کند، کامپایل را اجرا می‌کند و کلاس‌های آماده برای کار با این داده‌ها را دریافت می‌کند.

هر صحنه در پیام Protobuf یک شماره منحصر به فرد (field number) دارد — این شماره ترتیب نیست، بلکه برچسبی است که در فرمت دودویی برای شناسایی صحنه استفاده می‌شود. شماره‌های 1 تا 15 با یک بایت و شماره‌های 16 تا 2047 با دو بایت کدگذاری می‌شوند. بنابراین، صحنه‌های مهم با فرکانس بالای استفاده را بهتر است 1 تا 15 شماره‌گذاری کنید تا اندازه بهینه شود.

انواع داده Protobuf

Protobuf از طیف گسترده‌ای از انواع پشتیبانی می‌کند: اسکالر (int32, int64, float, double, bool, string, bytes)، شمرشی (enum)، مرکب (message) و ویژه (oneof, map). هر نوع یک نمایش دودویی مشخص دارد که برای سناریو استفاده مربوطه بهینه شده است.

نوع .proto نوع C++ Java/Kotlin توضیح
double double double عدد شناور 64-بیتی
float float float عدد شناور 32-بیتی
int32 int32 int 32-bit, variable-length encoding
int64 int64 long 64-bit, variable-length encoding
string string String رشته UTF-8
bytes string ByteString بایت‌های دلخواه
bool bool boolean true / false

مزایای فرمت دودویی

Protobuf سه مزیت کلیدی نسبت به فرمت‌های متنی ارائه می‌دهد: اندازه پیام، سرعت سریالی‌سازی و تایپ سختگیرانه. در سیستم‌های با بار بالا و نرم‌افزارهای موبایل با ترافیک محدود، این مزایا به مرتبه حیاتی می‌شوند.

نمایش دودویی Protobuf از variable-length encoding (Varint) برای اعداد استفاده می‌کند: اعداد کوچک 1 بایت و اعداد بزرگ تا 10 بایت جا می‌گیرند. این امکان کدگذاری مؤثر شناسایی‌ها، علمت‌ها و شمارنده‌ها را که در JSON یا XML دهه‌ها بایت به عنوان رشته‌های متنی اشغال می‌دادند، فراهم می‌کند. به عنوان مثال، عدد 150 در Protobuf 2 بایت، در JSON 3 بایت (به عنوان متن «150») و در XML 3 بایت + برچسب‌ها اشغال می‌دهد.

مزیت دیگر سازگاری به عقب است. افزودن صحنه جدید به شما مشتریان قدیمی را نمی‌شکند: آن‌ها صرفاً صحنه‌های ناشناخته را نادیده می‌گیرند. حذف صحنه فقط نیازمند ذخیره شماره آن است تا از تصادم در آینده جلوگیری شود.

تعریف شمای .proto

شمای .proto ساختار داده را به زبان ویژه‌ای توصیف می‌کند. فایل با مشخص کردن نحوه نگارش (proto3)، بسته و واردات وابستگی‌ها شروع می‌شود. هر پیام با کلمه کلیدی message با صحنه‌هایی تعریف می‌شود، که هر صحنه یک نوع، نام و شماره منحصر به فرد دارد.

قوانین شمای خوب: شماره صحنه‌های 1 تا 15 برای صحنه‌های پراستفاده، نام‌های معنی‌دار، گروه‌بندی صحنه‌های مرتبط در message جداگانه، استفاده از oneof برای صحنه‌هایی که فقط یکی از چند گزینه می‌توانند باشند.

protobuf
syntax = "proto3";

package mobileapp;

message User {
  string user_id = 1;
  string name = 2;
  string email = 3;
  int32 age = 4;
  UserRole role = 5;
  repeated string tags = 6;
  map<string, string> metadata = 7;
}

enum UserRole {
  USER_ROLE_UNSPECIFIED = 0;
  USER_ROLE_USER = 1;
  USER_ROLE_ADMIN = 2;
  USER_ROLE_MODERATOR = 3;
}

پیام‌های تودرو

پیام‌ها می‌توانند تودرو باشند: صحنه profile از نوع Profile داده‌های کاربر را در خود خواهد داشت. پشتیبانی از تودرویی امکان توصیف ساختارهای سلسله مراتب مرکب را بدون تکرار تعریف‌ها فراهم می‌کند.

protobuf
syntax = "proto3";

package mobileapp;

message Order {
  string order_id = 1;
  repeated OrderItem items = 2;
  double total_price = 3;
  PaymentInfo payment = 4;
}

message OrderItem {
  string product_id = 1;
  string title = 2;
  int32 quantity = 3;
  double price = 4;
}

message PaymentInfo {
  string method = 1;
  string transaction_id = 2;
  double amount = 3;
}

تولید کد از .proto

کامپایلر protoc فایل‌های .proto را به کد منبع در زبان مقصد تبدیل می‌کند. برای Kotlin/Java از پارامتر --java_out، برای Swift از --swift_out (از طریق پلاگین Apple Swift Protobuf)، برای Dart از --dart_out استفاده می‌شود. کلاس‌های تولیدشده شامل روش‌های builder برای ساخت پیام‌ها و روش‌های سریالی‌سازی/از سریالی‌زدایی هستند.

در Android برای کار با Protobuf از پلاگین com.google.protobuf نسخه 0.9+ در Gradle استفاده می‌شود. پس از افزودن پلاگین و مشخص کردن فایل‌های .proto، کامپایل به صورت خودکار کلاس‌های Kotlin را که برای استفاده در تطبیق آماده هستند تولید می‌کند.

kotlin
import com.google.protobuf.kotlin.toByteString
import com.example.mobileapp.UserOuterClass.User

fun createUser(): User {
    return User.newBuilder()
        .setUserId("usr_001")
        .setName("IT Sectr")
        .setEmail("team@itsectr.com")
        .setAge(5)
        .setRole(UserOuterClass.UserRole.USER_ROLE_ADMIN)
        .addTags("mobile")
        .addTags("backend")
        .build()
}

fun serializeAndDeserialize(user: User): User {
    // سریالی‌سازی به فرمت دودویی
    val bytes = user.toByteArray()

    // از سریالی‌زدایی از فرمت دودویی
    return User.parseFrom(bytes)
}

نمونه‌های استفاده از Protobuf

Protobuf به ویژه در معماری میکروسرویس و نرم‌افزارهای موبایل مؤثر است. یک سناریو معمولی را در نظر بگیرید: تطبیق موبایل از طریق gRPC لیست محصولات را از سرور دریافت می‌کند. پیام Protobuf شامل اطلاعات محصول، از جمله شناسایی، نام، قیمت و دسته است. فرمت دودویی اندازه پاسخ را در مقایسه با JSON 5-8 برابر کاهش می‌دهد.

خدمت gRPC در Kotlin

نمونه خدمت gRPC با Protobuf در طرف سرور. خدمت روش RPC GetProducts را بیان می‌کند که درخواست با پارامترهای صفحه‌بندی را می‌پذیرد و لیست محصولات را برمی‌گرداند. پیاده‌سازی در Kotlin از کلاس‌های تولیدشده برای کار با درخواست‌ها و پاسخ‌ها استفاده می‌کند.

kotlin
import com.example.mobileapp.ProductServiceGrpcKt
import com.example.mobileapp.ProductOuterClass.Product
import com.example.mobileapp.ProductOuterClass.GetProductsRequest
import com.example.mobileapp.ProductOuterClass.GetProductsResponse

class ProductService : ProductServiceGrpcKt.ProductServiceCoroutineImplBase() {

    override suspend fun getProducts(
        request: GetProductsRequest
    ): GetProductsResponse {
        val products = fetchProductsFromDb(
            page = request.page,
            limit = request.limit
        )

        return GetProductsResponse.newBuilder()
            .addAllProducts(products)
            .setTotalCount(products.size)
            .build()
    }
}

راه‌اندازی Protobuf در پروژه Android

راه‌اندازی Protobuf در پروژه Android از طریق پلاگین Gradle com.google.protobuf انجام می‌شود. پلاگین به صورت خودکار کامپایلر protoc را در زمان کامپایل اجرا کرده و از فایل‌های .proto کلاس‌های Kotlin تولید می‌کند. برای کار نیاز است پلاگین را در build.gradle سطح پروژه اضافه کرده و آن را در ماژول تطبیق اعمال کنید.

پس از تنظیم Gradle، فایل‌های .proto در شاخه src/main/proto قرار می‌گیرند. کامپایلر protoc آن‌ها را در هر کامپایل پردازش کرده و کلاس‌های Kotlin را تولید می‌کند که می‌توان در کد تطبیق استفاده کرد. مشخص کردن درست نسخه protobuf و protoc برای جلوگیری از تعارض وابستگی با سایر کتابخانه‌های پروژه مهم است.

برای پروژه‌های iOS، Protobuf از طریق CocoaPods یا Swift Package Manager متصل می‌شود. پلاگین Swift Protobuf به صورت خودکار ساختارهای Swift مطابق با پروتکل Codable را تولید می‌کند. در پروژه‌های Dart برای Flutter، از بسته protobuf استفاده شده و کامپایل از طریق dart run protoc_plugin انجام می‌شود.

سؤالات متداول

تفاوت بین Protobuf و JSON چیست؟

Protobuf — فرمات دودویی با شمای الزامی، 3-10 برابر فشرده‌تر از JSON. JSON — متنی، قابل خواندن توسط انسان، نیازی به شما ندارد. Protobuf سریع‌تر سریالی‌سازی و از سریالی‌زدایی می‌شود، اما نیازمند کامپایل فایل‌های .proto است. JSON در اشکال‌زدایی ساده‌تر است و نیازی به تنظیم قبلی ندارد.

چگونه کامپایلر protoc را نصب کنیم؟

protoc را از انتشار GitHub protobuf مربوط به پلتفرم خود دانلود کنید. برای macOS از طریق brew install protobuf نصب کنید. برای Windows بایگانی zip را دانلود کرده و protoc.exe را به PATH اضافه کنید. برای Android/Kotlin از پلاگین Gradle com.google.protobuf استفاده کنید که به صورت خودکار کامپایل را در زمان ساخت اجرا می‌کند.

gRPC چیست و چگونه با Protobuf مرتبط است؟

gRPC — یک چارچوب RPC با عملکرد بالا از Google است که از Protobuf به عنوان زبان رابط (IDL) و فرمت سریالی‌سازی استفاده می‌کند. gRPC خدمات و روش‌های RPC را در فایل‌های .proto تعریف می‌کند، کد مشتری و سرور را تولید می‌کند، از انتقال جریانی و پروتکل‌های دودویی پشتیبانی می‌کند.

Protobuf چه زبان‌هایی را پشتیبانی می‌کند؟

Google به صورت رسمی پشتیبانی می‌کند: C++، Java، Kotlin، Python، Go، Ruby، C#، PHP، JavaScript، Objective-C، Swift و Dart. جامعه پشتیبانی از Rust، TypeScript، Scala، Lua و سایر زبان‌ها را فراهم کرده است. برای توسعه موبایل، Kotlin/Java (Android) و Swift/Objective-C (iOS) موجود است.

چگونه سازگاری به عقب شماها را تضمین کنیم؟

Protobuf از سازگاری به عقب از طریق قوانین زیر پشتیبانی می‌کند: شماره صحنه‌ها را تغییر ندهید، صحنه‌ها را حذف نکنید (از reserved استفاده کنید)، صحنه‌های جدید را با شماره‌های جدید اضافه کنید. مشتریان قدیمی صحنه‌های ناشناخته را نادیده می‌گیرند، مشتریان جدید مقادیر پیش‌فرض را برای صحنه‌های گمشده قدیمی دریافت می‌کنند.

خلاصه

  • Protocol Buffers — فرمات سریالی‌سازی دودویی از Google با شمای الزامی داده
  • اندازه پیام 3-10 برابر کوچک‌تر از JSON به دلیل کدگذاری Varint
  • سرعت سریالی‌سازی و از سریالی‌زدایی بالاتر از فرمات‌های متنی
  • شمای .proto تایپ سختگیرانه و تولید کد برای 12+ زبان را تامین می‌کنند
  • سازگاری به عقب به API اجازه تکامل بدون شکستن مشتریان را می‌دهد
  • gRPC از Protobuf به عنوان فرمات استاندارد برای ارتباط میکروسرویس استفاده می‌کند
  • ایده‌آل برای سیستم‌های با بار بالا و نرم‌افزارهای موبایل با ترافیک محدود

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید