إنشاء الشيفرة باستخدام tonic-build
حوّل proto إلى Rust
إنشاء الشيفرة باستخدام tonic-build درس مجاني في Learn Rust Coding على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Learn Rust Coding، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Learn Rust Coding 4 دروس في المجموع.
ما الذي يفعله tonic-build
تعمل tonic-build وقت الترجمة وتحول ملفات .proto إلى مصدر Rust. وهي تغلّف prost-build للرسائل، وتضيف سمات خدمات gRPC وعملاءها.
وتُشغَّل من نص بناء Cargo (build.rs)، لذلك يحدث التوليد تلقائيًا قبل ترجمة الحزمة.
تبعيات Cargo
تحتاجون إلى حزم وقت التشغيل وحزمة وقت البناء. تُعدّ tonic وprost تبعيتين عاديتين، بينما توضع tonic-build ضمن [build-dependencies].
تعتمد tonic على tokio بوصفها بيئة التشغيل غير المتزامنة، لذا أدرجوها أيضًا.
[dependencies]
tonic = "0.12"
prost = "0.13"
tokio = { version = "1", features = ["full"] }
[build-dependencies]
tonic-build = "0.12"ملف build.rs بسيط
أنشئوا build.rs في جذر الحزمة. واستدعوا tonic_build::compile_protos مع مسار ملف proto.
يترجم هذا شيفرة العميل والخادم افتراضيًا، ويكتبها إلى OUT_DIR الخاص بـ Cargo.
fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::compile_protos("proto/greeter.proto")?;
Ok(())
}تهيئة أداة البناء
لمزيد من التحكم، استخدموا tonic_build::configure(). يمكنكم تعطيل توليد العميل أو الخادم، وتعيين مسارات الإخراج، أو إضافة سمات للأنواع.
نولّد الخادم هنا ونتجاوز العميل، وهو أمر مفيد لحزمة خلفية بحتة.
tonic_build::configure()
.build_client(false)
.build_server(true)
.compile_protos(&["proto/greeter.proto"], &["proto"])?;مسارات التضمين
الوسيط الثاني لـ compile_protos هو قائمة أدلة التضمين. وتُحلّ عمليات الاستيراد داخل proto، مثل google/protobuf/empty.proto، بالاعتماد على هذه الجذور.
أدرجوا دائمًا الدليل الذي يحتوي على ملفات proto حتى تُحلّ عمليات الاستيراد بين الملفات.
tonic_build::configure()
.compile_protos(
&["proto/greeter.proto", "proto/health.proto"],
&["proto"],
)?;مكان وضع الشيفرة
تُكتب الملفات المولَّدة في الدليل المحدد في متغير البيئة OUT_DIR، وتُسمّى وفق حزمة proto، مثل greeter.v1.rs.
تُدخلونها إلى حزمتكم باستخدام الماكرو include_proto! داخل وحدة.
pub mod greeter {
pub mod v1 {
tonic::include_proto!("greeter.v1");
}
}ما الذي يتم توليده
ينتج tonic لكل خدمة وحدة خادم تتضمن سمة (مثل greeter_server::Greeter) وغلاف GreeterServer، بالإضافة إلى بنية العميل GreeterClient.
تتحول كل رسالة إلى بنية Rust ترث Clone وPartialEq وMessage الخاصة بـ prost.
// generated (sketch):
// pub mod greeter_server { pub trait Greeter { /* methods */ } }
// pub mod greeter_client { pub struct GreeterClient<T> { /* ... */ } }إضافة اشتقاقات باستخدام type_attribute
غالبًا ما تحتاجون إلى اشتقاقات إضافية في البنى المولَّدة، مثل serde::Serialize. استخدموا type_attribute لحقن السمات في أنواع محددة أو في جميع الأنواع باستخدام ..
يتيح ذلك تمرير الرسائل المولَّدة إلى واجهات JSON أو تركيبات الاختبار.
tonic_build::configure()
.type_attribute(".", "#[derive(serde::Serialize)]")
.compile_protos(&["proto/greeter.proto"], &["proto"])?;تشغيل عمليات إعادة البناء
يعيد Cargo تشغيل build.rs فقط عندما يعتقد أن المدخلات تغيرت. أصدروا أسطر cargo:rerun-if-changed حتى تؤدي تعديلات ملفات proto إلى فرض إعادة التوليد.
من دون ذلك، قد لا يُعاد توليد proto المعدّل حتى تلمسوا ملف Rust.
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("cargo:rerun-if-changed=proto/greeter.proto");
tonic_build::compile_protos("proto/greeter.proto")?;
Ok(())
}متطلب protoc
تاريخيًا، كان tonic-build يستدعي مترجم protoc من خلال الصدفة، وكان يجب تثبيته. أما الإصدارات الحديثة فيمكنها استخدام محلل protox المكتوب بالكامل بلغة Rust لتجنب هذه التبعية.
إذا ظهر لكم خطأ يفيد بفقدان protoc، فثبّتوا protoc أو فعّلوا ميزة مترجم مضمَّن.
// In CI you may install protoc, e.g.:
// apt-get install -y protobuf-compilerمجموعات واصفات الملفات
بالنسبة إلى الانعكاس أو أدوات التطوير المتقدمة، اطلبوا من tonic-build إصدار مجموعة واصفات ملفات باستخدام file_descriptor_set_path.
يمكن تمرير البايتات الناتجة إلى tonic-reflection، مما يتيح لأدوات مثل grpcurl اكتشاف خدماتكم وقت التشغيل.
tonic_build::configure()
.file_descriptor_set_path(
std::env::var("OUT_DIR").unwrap() + "/greeter.bin")
.compile_protos(&["proto/greeter.proto"], &["proto"])?;تحقق سريع
أين توضع شيفرة tonic المولَّدة، وكيف تُحمَّل؟
مراجعة
أعددتم التبعيات، وكتبتم build.rs، وهيّأتم توليد العميل والخادم ومسارات التضمين، وحمّلتم الشيفرة عبر include_proto!، وأضفتم الاشتقاقات، وعالجتم محفزات إعادة البناء، وتعرّفتم إلى protoc ومجموعات الواصفات.
ستطبّقون بعد ذلك سمة الخادم التي ولّدها tonic.
الأسئلة الشائعة
هل درس «إنشاء الشيفرة باستخدام tonic-build» مجاني؟
نعم — نص درس «إنشاء الشيفرة باستخدام tonic-build» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Learn Rust Coding، انتقل إلى CoddyKit PRO. تتضمن دورة Learn Rust Coding 4 دروس في المجموع.
ماذا ستتعلم في «إنشاء الشيفرة باستخدام tonic-build»؟
حوّل proto إلى Rust تتمرن على Learn Rust Coding مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Learn Rust Coding؟
لا تُشترط خبرة سابقة. Learn Rust Coding على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «إنشاء الشيفرة باستخدام tonic-build»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Learn Rust Coding هذا؟
نعم. كل درس في Learn Rust Coding يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- تعريفات Protobuf والخدمات
- إنشاء الشيفرة باستخدام tonic-build
- تنفيذ خادم gRPC
- الاستدعاء من عميل gRPC