Protobuf — strukturali ma’lumotlarni schema asosida compact binary ko‘rinishda serialize qilish tizimi. To‘liq nomi Protocol Buffers. Message va fieldlar .proto faylda belgilanadi, keyin turli dasturlash tillari uchun code generator class va API yaratadi.
Protobuf service communication, event, storage va gRPC ekotizimida keng qo‘llanadi.
Proto fayl
Schema misoli:
syntax = "proto3";
message User {
int64 id = 1;
string name = 2;
bool active = 3;
}
Har field type, nom va unique field numberga ega.
Field number wire formatning muhim qismi.
Message
message strukturali obyektni ifodalaydi.
Message ichida:
- scalar;
- enum;
- nested message;
- repeated field;
- map;
- oneof
bo‘lishi mumkin.
Generated class type-safe setter, getter va serialization methodlarini beradi.
Field number
Har fieldga raqam beriladi:
string name = 2;
Binary payloadda ko‘pincha field nomi emas, shu raqam ishlatiladi.
Bu payloadni kichraytiradi.
Raqam keyinchalik boshqa ma’no uchun qayta ishlatilmasligi kerak.
Wire type
Field number wire type bilan birga tag hosil qiladi.
Wire type parserga qiymat qanday kodlanganini bildiradi:
- varint;
- fixed-width;
- length-delimited;
- boshqa format.
Schema business type’ni aniq belgilaydi.
Varint
Kichik integerlar kam byte bilan yoziladi.
Varint har byte’da qiymatning bir qismini saqlaydi.
Katta musbat sonlar ko‘proq byte oladi.
Signed sonlar uchun zigzag encodingga oid type’lar manfiy qiymatni compact saqlashi mumkin.
Scalar turlar
Protobuf scalar turlari:
- integer variantlari;
- float;
- double;
- bool;
- string;
- bytes.
Integer type tanlash diapazon va wire encodingga ta’sir qiladi.
bytes raw binary uchun ishlatiladi.
Enum
Enum nomlangan numeric qiymatlar to‘plami:
enum Status {
STATUS_UNSPECIFIED = 0;
ACTIVE = 1;
DISABLED = 2;
}
Default nol qiymat bo‘lishi kerak.
UNSPECIFIED kelajak va default holatni aniq ko‘rsatadi.
Repeated
Ro‘yxat:
repeated string roles = 4;
Empty list va field mavjud emasligi proto versiyasi hamda generated API’da o‘xshash ko‘rinishi mumkin.
Katta repeated field message hajmini oshiradi.
Map
Map sintaksisi:
map<string, string> labels = 5;
Wire formatda map entry message’lariga o‘xshash kodlanadi.
Map tartibiga tayanmaslik kerak.
Deterministic serialization alohida option bo‘lishi mumkin.
Nested message
Message ichida boshqa message type ishlatiladi:
message User {
Address address = 6;
}
Nested structure business modelni ifodalaydi.
Juda chuqur message parser depth va payload complexityni oshiradi.
Oneof
Bir nechta fielddan faqat bittasi active bo‘lishini ko‘rsatadi:
oneof contact {
string email = 7;
string phone = 8;
}
Yangi qiymat berilganda oldingi oneof field tozalanadi.
Bu unionga o‘xshash model.
Unknown field
Eski client yangi fieldni bilmasa uni odatda parse jarayonida e’tiborsiz qoldiradi yoki saqlab qayta uzatishi mumkin.
Bu forward compatibilityga yordam beradi.
Ammo application noma’lum fieldga business qaror qilmaydi.
Schema evolyutsiyasi
Backward-compatible o‘zgarishlar:
- yangi optional field;
- yangi enum qiymati ehtiyotkorlik bilan;
- yangi message;
- yangi method.
Xavfli o‘zgarishlar:
- field numberni qayta ishlatish;
- wire type’ni mos kelmaydigan almashtirish;
- requiredga oid eski semantika;
- enum behaviorini noto‘g‘ri talqin qilish.
O‘chirilgan field raqami reserved qilinadi.
Default qiymat
Proto3 scalar field o‘qilganda default qiymat qaytishi mumkin:
- son — 0;
- bool — false;
- string — bo‘sh.
Field aynan yuborilganmi yoki yo‘qmi ayrim holatda presence capability’siga bog‘liq.
Business semantika default bilan “ma’lum emas”ni adashtirmasligi kerak.
Code generation
Compiler .protodan tilga mos code yaratadi.
Afzalligi:
- type safety;
- parser yozmaslik;
- contract birligi;
- documentation;
- integration.
Generated file qo‘lda tahrirlanmaydi.
Schema source sifatida saqlanadi.
JSON mapping
Protobuf message’ni JSONga aylantirish uchun standard mapping mavjud.
64-bit integer, enum, bytes va timestamp oddiy JSONdan farqli qoidalarga ega bo‘lishi mumkin.
Client custom JSON serializer bilan contractni buzmasligi kerak.
Protobuf va gRPC
gRPC service methodlari request va response uchun Protobuf message ishlatishi keng tarqalgan.
Protobuf serializationni, gRPC esa transport, method, status, deadline va streamingni beradi.
Protobufni gRPCsiz ham ishlatish mumkin.
Security
Parser quyidagilarni cheklaydi:
- message hajmi;
- recursion depth;
- repeated element soni;
- string/bytes hajmi;
- unknown field;
- decompression.
Generated type bo‘lishi authorization yoki business validationni avtomatik ta’minlamaydi.
Descriptor
Protobuf schema compiler descriptor ko‘rinishida ham ifodalanishi mumkin. Descriptor message, field, enum va service metadata’sini machine-readable tarzda saqlaydi. Dynamic parser yoki reflection descriptor yordamida oldindan generated classsiz message’ni talqin qilishi mumkin. Productionda qaysi schema versiyasi trusted ekanini registry yoki package nazorat qiladi.
Packed repeated field
Numeric repeated fieldlar packed encoding bilan compact yozilishi mumkin. Bir tag ostida bir nechta qiymat length-delimited blokda saqlanadi. Parser packed va unpacked ko‘rinishlarni compatibility qoidalariga ko‘ra qabul qilishi mumkin.
Deterministik serialization
Protobuf byte output har doim canonical hash format emas. Map tartibi va unknown fieldlar representationga ta’sir qilishi mumkin. Signature kerak bo‘lsa deterministic option va aniq canonical contract ishlatiladi.
Package nomi
package declaration generated type nomlarini namespace ichida saqlaydi va turli schema’larda bir xil message nomi to‘qnashuvini kamaytiradi.
Bog‘liq tushunchalar
Protocol Buffers, Proto file, Message, Field number, Varint, Schema evolution, Code generation, gRPC, Binary serialization, Wire format