Protocol Buffers (Protobuf) হল স্ট্রাকচার্ড ডেটার জন্য একটি বাইনারি সিরিয়ালাইজেশন ফর্ম্যাট, যা Google পরিষেবাগুলির মধ্যে দক্ষ তথ্য বিনিময়ের জন্য তৈরি করেছে। ফর্ম্যাটটির জন্য .proto ফাইলগুলিতে পূর্বনির্ধারিত স্কিমা প্রয়োজন, যেখান থেকে বিভিন্ন ভাষার জন্য কোড জেনারেট করা হয়। Google-এর অফিসিয়াল ডকুমেন্টেশন অনুযায়ী, Protobuf JSON-এর চেয়ে 3-10 গুণ ছোট মেসেজ সাইজ প্রদান করে। Protobuf gRPC, Google Maps এবং হাজার হাজার অভ্যন্তরীণ পরিষেবায় ব্যবহৃত হয়।
মূল বিষয়
Protocol Buffers হল Google-এর তৈরি একটি স্ট্রাকচার্ড ডেটা সিরিয়ালাইজেশন মেকানিজম, যা JSON এবং XML-এর মতো, তবে একটি মৌলিক পার্থক্য সহ: ডেটা বাইনারি ফর্ম্যাটে এনকোড করা হয়। এর অর্থ হল একটি Protobuf মেসেজ খালি চোখে পড়া যায় না, তবে এটি উল্লেখযোগ্যভাবে কম জায়গা নেয় এবং টেক্সট-ভিত্তিক প্রতিরূপের চেয়ে দ্রুত প্রক্রিয়াকরণ করে।
Protobuf Google-এর অভ্যন্তরে পরিষেবাগুলির মধ্যে ডেটা বিনিময়ে পারফরম্যান্স সমস্যা সমাধানের জন্য তৈরি করা হয়েছিল। 2008 সালে, প্রযুক্তিটি অনেক ভাষার সমর্থন সহ একটি ওপেন-সোর্স প্রকল্পে পরিণত হয়: C++, Java, Python, Go, JavaScript, Kotlin, Swift, Dart এবং অন্যান্য। 2016 সালে প্রকাশিত proto3 সংস্করণ, সিনট্যাক্স সরল করেছে এবং আরও ভাষার জন্য সমর্থন যোগ করেছে।
Protobuf এবং JSON-এর মধ্যে মূল পার্থক্য হল ডেটা বিনিময় শুরু হওয়ার আগে একটি স্কিমা সংজ্ঞায়িত করার প্রয়োজনীয়তা। স্কিমা ফাইল (.proto) মেসেজ স্ট্রাকচার বর্ণনা করে: ফিল্ড, টাইপ এবং অনন্য ফিল্ড নম্বর। এই স্কিমা থেকে, protoc কম্পাইলার সিরিয়ালাইজেশন এবং ডিসিরিয়ালাইজেশনের জন্য টার্গেট ভাষায় ক্লাস জেনারেট করে।
Protobuf আর্কিটেকচার তিনটি মূল উপাদান অন্তর্ভুক্ত করে: স্কিমা সংজ্ঞা ভাষা (.proto), protoc কম্পাইলার, এবং নির্দিষ্ট ভাষার জন্য রানটাইম লাইব্রেরি। ডেভেলপার .proto ফাইলে ডেটা স্ট্রাকচার বর্ণনা করে, কম্পাইলেশন চালায়, এবং এই ডেটার সাথে কাজ করার জন্য প্রস্তুত ক্লাস গ্রহণ করে।
Protobuf মেসেজের প্রতিটি ফিল্ডের একটি অনন্য নম্বর (ফিল্ড নম্বর) থাকে — এটি একটি ক্রমিক নম্বর নয়, বরং একটি ট্যাগ যা বাইনারি ফর্ম্যাটে ফিল্ড সনাক্ত করতে ব্যবহৃত হয়। 1 থেকে 15 নম্বর এক বাইটে এনকোড হয়, 16 থেকে 2047 — দুই বাইটে। তাই, উচ্চ ব্যবহার ফ্রিকোয়েন্সি সহ গুরুত্বপূর্ণ ফিল্ডগুলি আকার অনুকূলনের জন্য 1 থেকে 15 নম্বর দেওয়া উচিত।
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-বিট, পরিবর্তনশীল-দৈর্ঘ্য এনকোডিং |
| int64 | int64 | long | 64-বিট, পরিবর্তনশীল-দৈর্ঘ্য এনকোডিং |
| string | string | String | UTF-8 স্ট্রিং |
| bytes | string | ByteString | ইচ্ছামত বাইট |
| bool | bool | boolean | true / false |
Protobuf টেক্সট-ভিত্তিক ফর্ম্যাটের তুলনায় তিনটি মূল সুবিধা প্রদান করে: মেসেজ সাইজ, সিরিয়ালাইজেশন গতি, এবং কঠোর টাইপিং। উচ্চ-লোড সিস্টেম এবং সীমিত ট্রাফিক সহ মোবাইল অ্যাপ্লিকেশনে, এই সুবিধাগুলি গুরুত্বপূর্ণ হয়ে ওঠে।
Protobuf-এর বাইনারি উপস্থাপনা সংখ্যার জন্য পরিবর্তনশীল-দৈর্ঘ্য এনকোডিং (Varint) ব্যবহার করে: ছোট সংখ্যা 1 বাইট নেয়, বড় সংখ্যা — 10 বাইট পর্যন্ত। এটি আইডেন্টিফায়ার, ফ্ল্যাগ এবং কাউন্টারগুলিকে দক্ষভাবে এনকোড করতে দেয় যা JSON বা XML-এ টেক্সট স্ট্রিং হিসাবে দশ বাইট নেয়। উদাহরণস্বরূপ, 150 সংখ্যা Protobuf-এ 2 বাইট নেয়, JSON-এ — 3 বাইট (“150” টেক্সট হিসাবে), XML-এ — 3 বাইট + ট্যাগ।
একটি অতিরিক্ত সুবিধা হল পশ্চাদগামী সামঞ্জস্য। স্কিমায় নতুন ফিল্ড যোগ করলে পুরানো ক্লায়েন্ট ভাঙে না: তারা কেবল অজানা ফিল্ড উপেক্ষা করে। ফিল্ড মুছে ফেলার জন্য ভবিষ্যতে সংঘর্ষ এড়াতে শুধুমাত্র এর নম্বর সংরক্ষণ করা প্রয়োজন।
.proto স্কিমা একটি বিশেষ ভাষায় ডেটা স্ট্রাকচার বর্ণনা করে। ফাইলটি সিনট্যাক্স (proto3), প্যাকেজ এবং ইমপোর্ট নির্ভরতা উল্লেখ করে শুরু হয়। প্রতিটি মেসেজ কীওয়ার্ড message দিয়ে ফিল্ড সহ সংজ্ঞায়িত করা হয়, যেখানে প্রতিটি ফিল্ডের একটি টাইপ, নাম এবং অনন্য নম্বর থাকে।
ভাল স্কিমা অনুশীলন: ঘন ঘন ব্যবহৃত ফিল্ডের জন্য 1 থেকে 15 ফিল্ড নম্বর, অর্থপূর্ণ নাম, সম্পর্কিত ফিল্ড আলাদা message-এ গ্রুপ করা, ফিল্ডের জন্য oneof ব্যবহার করা যা একাধিক বিকল্পের মধ্যে শুধুমাত্র একটি হতে পারে।
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 ফিল্ড ভিতরে ইউজার ডেটা ধারণ করবে। নেস্টিং সমর্থন সংজ্ঞা ডুপ্লিকেট না করে জটিল শ্রেণিবদ্ধ কাঠামো বর্ণনা করতে দেয়।
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;
}
protoc কম্পাইলার .proto ফাইলগুলিকে টার্গেট ভাষায় সোর্স কোডে রূপান্তর করে। Kotlin/Java-র জন্য --java_out প্যারামিটার ব্যবহার করা হয়, Swift-এর জন্য --swift_out (Apple Swift Protobuf প্লাগইনের মাধ্যমে), Dart-এর জন্য --dart_out। জেনারেটেড ক্লাসে মেসেজ নির্মাণের জন্য builder মেথড এবং সিরিয়ালাইজেশন/ডিসিরিয়ালাইজেশন মেথড থাকে।
Android-এ, Protobuf-এর সাথে কাজ করার জন্য Gradle-এ com.google.protobuf প্লাগইন সংস্করণ 0.9+ ব্যবহার করা হয়। প্লাগইন যোগ এবং .proto ফাইল নির্দিষ্ট করার পর, বিল্ড স্বয়ংক্রিয়ভাবে অ্যাপ্লিকেশনে ব্যবহারের জন্য প্রস্তুত 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 বিশেষ করে মাইক্রোসার্ভিস আর্কিটেকচার এবং মোবাইল অ্যাপ্লিকেশনে কার্যকর। একটি সাধারণ পরিস্থিতি বিবেচনা করুন: একটি মোবাইল অ্যাপ্লিকেশন gRPC-এর মাধ্যমে সার্ভার থেকে পণ্যের তালিকা গ্রহণ করে। Protobuf মেসেজে শনাক্তকারী, নাম, মূল্য এবং ক্যাটাগরি সহ পণ্যের তথ্য থাকে। বাইনারি ফর্ম্যাট JSON-এর তুলনায় প্রতিক্রিয়ার আকার 5-8 গুণ কমায়।
সার্ভার সাইডে Protobuf সহ gRPC পরিষেবার উদাহরণ। পরিষেবাটি GetProducts RPC মেথড ঘোষণা করে, যা পেজিনেশন প্যারামিটার সহ অনুরোধ গ্রহণ করে এবং পণ্যের তালিকা ফেরত দেয়। 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()
}
}
Android প্রকল্পে Protobuf সেটআপ com.google.protobuf Gradle প্লাগইনের মাধ্যমে করা হয়। প্লাগইন বিল্ডের সময় স্বয়ংক্রিয়ভাবে protoc কম্পাইলার চালায় এবং .proto ফাইল থেকে Kotlin ক্লাস জেনারেট করে। কাজ করার জন্য, আপনাকে প্রকল্প-স্তরের build.gradle-এ প্লাগইন যোগ করতে হবে এবং অ্যাপ্লিকেশন মডিউলে এটি প্রয়োগ করতে হবে।
Gradle কনফিগার করার পর, .proto ফাইলগুলি src/main/proto ডিরেক্টরিতে রাখা হয়। protoc কম্পাইলার প্রতিটি বিল্ডের সময় সেগুলি প্রক্রিয়া করে, Kotlin ক্লাস জেনারেট করে যা অ্যাপ্লিকেশন কোডে ব্যবহার করা যেতে পারে। প্রকল্পের অন্যান্য লাইব্রেরির সাথে নির্ভরতা দ্বন্দ্ব এড়াতে সঠিকভাবে protobuf এবং protoc সংস্করণ নির্দিষ্ট করা গুরুত্বপূর্ণ।
iOS প্রকল্পের জন্য, Protobuf CocoaPods বা Swift Package Manager-এর মাধ্যমে সংযুক্ত করা হয়। Swift Protobuf প্লাগইন স্বয়ংক্রিয়ভাবে Codable প্রোটোকল মেনে চলা Swift স্ট্রাকচার জেনারেট করে। Flutter-এর জন্য Dart প্রকল্পে, protobuf প্যাকেজ ব্যবহার করা হয়, এবং কম্পাইলেশন dart run protoc_plugin-এর মাধ্যমে করা হয়।
সচরাচর জিজ্ঞাসা
Protobuf একটি বাধ্যতামূলক স্কিমা সহ একটি বাইনারি ফর্ম্যাট, JSON-এর চেয়ে 3-10 গুণ বেশি কমপ্যাক্ট। JSON টেক্সট-ভিত্তিক, মানব-পাঠযোগ্য এবং স্কিমার প্রয়োজন হয় না। Protobuf দ্রুত সিরিয়ালাইজ এবং ডিসিরিয়ালাইজ করে কিন্তু .proto ফাইল কম্পাইলেশন প্রয়োজন। JSON ডিবাগ করা সহজ এবং পূর্ব-সেটআপের প্রয়োজন হয় না।
আপনার প্ল্যাটফর্মের জন্য protobuf GitHub রিলিজ থেকে protoc ডাউনলোড করুন। macOS-এর জন্য, brew install protobuf-এর মাধ্যমে ইনস্টল করুন। Windows-এর জন্য, জিপ আর্কাইভ ডাউনলোড করুন এবং PATH-এ protoc.exe যোগ করুন। Android/Kotlin-এর জন্য, com.google.protobuf Gradle প্লাগইন ব্যবহার করুন, যা বিল্ডের সময় স্বয়ংক্রিয়ভাবে কম্পাইলেশন চালায়।
gRPC হল Google-এর একটি উচ্চ-পারফরম্যান্স RPC ফ্রেমওয়ার্ক যা Protobuf-কে তার ইন্টারফেস সংজ্ঞা ভাষা (IDL) এবং সিরিয়ালাইজেশন ফর্ম্যাট হিসাবে ব্যবহার করে। gRPC .proto ফাইলে পরিষেবা এবং RPC মেথড সংজ্ঞায়িত করে, ক্লায়েন্ট এবং সার্ভার কোড জেনারেট করে, এবং স্ট্রিমিং এবং বাইনারি প্রোটোকল সমর্থন করে।
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 ব্যবহার করুন), নতুন নম্বর দিয়ে নতুন ফিল্ড যোগ করুন। পুরানো ক্লায়েন্ট অজানা ফিল্ড উপেক্ষা করে, নতুন ক্লায়েন্ট অনুপস্থিত পুরানো ফিল্ডের জন্য ডিফল্ট মান পায়।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন