Learn Rust Coding · درس

إعداد المشروع

هيكلة API

الدرس 1 من 413 خطوة

إعداد المشروع درس مجاني في Learn Rust Coding على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Learn Rust Coding، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Learn Rust Coding 4 دروس في المجموع.

بناء REST API باستخدام Rust

في هذه الدورة، ستبني REST API صغيرة باستخدام Rust. سنستخدم إطار الويب Axum، المبني على Tokio (بيئة تشغيل غير متزامنة) وTower (البرمجيات الوسيطة). ويتميز بسهولة الاستخدام وأمان الأنواع، ويُستخدم على نطاق واسع في بيئات الإنتاج.

يهيئ هذا الدرس الأول بنية المشروع، بحيث يمكن للدروس اللاحقة إضافة المسارات والنماذج وقاعدة البيانات والاختبارات.

إنشاء المشروع

ابدأ باستخدام Cargo. يمنحك المشروع الثنائي نقطة دخول هي src/main.rs:

  • ينشئ cargo new rest_api المجلد.
  • ينقلك cd rest_api إليه.
  • ينشئ cargo run المشروع ويشغّله.

هذه أوامر shell وcargo، وليست مقاطع Rust قابلة للتشغيل.

// terminal
// cargo new rest_api
// cd rest_api
// cargo run

إضافة الاعتماديات

تحتاج واجهة Axum البرمجية إلى بضع حزم في Cargo.toml:

  • axum للتوجيه ومعالجات الطلبات.
  • tokio لبيئة التشغيل غير المتزامنة.
  • serde لتسلسل JSON.
// Cargo.toml
// [dependencies]
// axum = "0.7"
// tokio = { version = "1", features = ["full"] }
// serde = { version = "1", features = ["derive"] }
// serde_json = "1"

بيئة التشغيل async

تعالج خوادم الويب العديد من الاتصالات بالتزامن، ولذلك فإن Axum غير متزامن. تحوّل السمة #[tokio::main] الدالة main غير المتزامنة إلى نقطة دخول فعلية من خلال بدء بيئة تشغيل Tokio. ويمكن لكل معالج استخدام .await لإجراء عمليات إدخال وإخراج غير حاجزة.

// src/main.rs
use tokio;

#[tokio::main]
async fn main() {
    println!("runtime started");
}

خادم بسيط

ينشئ تطبيق Axum الأصغر Router، ويربط مستمع TCP، ثم يقدّم الخدمة. ويربط مسار واحد GET / بمعالج يعيد سلسلة نصية. والمعالجات ليست سوى دوال غير متزامنة تعيد قيمة تطبّق IntoResponse.

use axum::{routing::get, Router};

#[tokio::main]
async fn main() {
    let app = Router::new().route("/", get(root));
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
        .await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

async fn root() -> &'static str {
    "Hello, API!"
}

كيفية عمل التوجيه

يربط Router مسارًا وطريقة HTTP بمعالج. استخدم سلسلة من استدعاءات .route(path, method(handler)) لتسجيل نقاط النهاية. وتأتي مساعدات الطرق مثل get وpost وput وdelete من axum::routing. ويمكنك دمج عدة طرق في المسار نفسه.

use axum::{routing::{get, post}, Router};

async fn list() -> &'static str { "list" }
async fn create() -> &'static str { "created" }

fn build_router() -> Router {
    Router::new()
        .route("/items", get(list).post(create))
        .route("/health", get(|| async { "ok" }))
}

التخطيط الموصى به للوحدات

مع نمو واجهة API، قسّم الشيفرة إلى وحدات بدلًا من وضعها في main.rs ضخم واحد:

  • main.rs — بدء التشغيل وربط الخادم.
  • routes.rs — تعريف الموجّه.
  • handlers.rs — معالجات الطلبات.
  • models.rs — هياكل البيانات.

يحافظ هذا الفصل على تركيز كل ملف، ويسهّل اختباره.

// src/main.rs
mod routes;
mod handlers;
mod models;

#[tokio::main]
async fn main() {
    let app = routes::build();
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
        .await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

حالة التطبيق المشتركة

تحتاج معظم واجهات API إلى حالة مشتركة، مثل مجموعة اتصالات قاعدة بيانات أو مخزن موجود في الذاكرة. يحتفظ بها Axum باستخدام .with_state(state) على الموجّه. وتتلقى المعالجات هذه الحالة عبر مستخرج State. ويجب أن تكون الحالة Clone؛ لذا غلّف البيانات القابلة للتغيير داخل Arc وقفل.

use axum::{routing::get, Router, extract::State};
use std::sync::{Arc, Mutex};

type Db = Arc<Mutex<Vec<String>>>;

async fn count(State(db): State<Db>) -> String {
    let n = db.lock().unwrap().len();
    format!("{} items", n)
}

fn build(db: Db) -> Router {
    Router::new().route("/count", get(count)).with_state(db)
}

إعادة JSON

لإرسال JSON، غلّف قيمة قابلة للتسلسل داخل axum::Json. وعند اشتقاق Serialize باستخدام serde على هياكلك، يضبط Axum نوع المحتوى والجسم تلقائيًا.

use axum::Json;
use serde::Serialize;

#[derive(Serialize)]
struct Status {
    service: String,
    healthy: bool,
}

async fn health() -> Json<Status> {
    Json(Status { service: "api".into(), healthy: true })
}

الإعداد والمنافذ

لا بأس من تثبيت رقم المنفذ في العروض التوضيحية، لكن الخدمات الفعلية تقرأ الإعدادات من البيئة. استخدم std::env::var مع قيمة افتراضية. يتيح لك ذلك تغيير عنوان الربط دون إعادة الترجمة، كما ينسجم جيدًا مع الحاويات.

use std::env;

async fn main_inner() {
    let port = env::var("PORT").unwrap_or_else(|_| "3000".to_string());
    let addr = format!("0.0.0.0:{}", port);
    println!("binding to {}", addr);
    // bind and serve with addr ...
}

جمع إعدادات التشغيل

يربط بدء التشغيل الكامل جميع الأجزاء: أنشئ الموجّه مع المسارات والحالة المشتركة، واقرأ رقم المنفذ، واربط مستمعًا، ثم شغّل الخدمة. وبعد تجهيز هذا الهيكل الأساسي، تضيف الدروس التالية نقاط نهاية ونماذج وتخزينًا دائمًا فعلية.

use axum::{routing::get, Router};
use std::sync::{Arc, Mutex};

#[tokio::main]
async fn main() {
    let db = Arc::new(Mutex::new(Vec::<String>::new()));
    let app = Router::new()
        .route("/health", get(|| async { "ok" }))
        .with_state(db);
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
        .await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

اختبار سريع

اختبر مدى فهمك لإعداد المشروع.

مراجعة

لقد أعددت مشروع REST API باستخدام Rust:

  • استخدم cargo new وأضف axum وtokio وserde.
  • توفر #[tokio::main] بيئة التشغيل غير المتزامنة.
  • يربط Router المسارات والطرق بالمعالجات غير المتزامنة.
  • شارك البيانات باستخدام .with_state ومستخرج State.
  • قسّم الشيفرة إلى وحدات للمسارات والمعالجات والنماذج، واقرأ رقم المنفذ من البيئة.
البدء مجانًا

تعلم Rust مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
39
الدروس
144

الأسئلة الشائعة

هل درس «إعداد المشروع» مجاني؟

نعم — نص درس «إعداد المشروع» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Learn Rust Coding، انتقل إلى CoddyKit PRO. تتضمن دورة Learn Rust Coding 4 دروس في المجموع.

ماذا ستتعلم في «إعداد المشروع»؟

هيكلة API تتمرن على Learn Rust Coding مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Learn Rust Coding؟

لا تُشترط خبرة سابقة. Learn Rust Coding على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «إعداد المشروع»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Learn Rust Coding هذا؟

نعم. كل درس في Learn Rust Coding يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. إعداد المشروع
  2. نقاط النهاية والنماذج
  3. تكامل قاعدة البيانات
  4. اختبار API
← العودة إلى Learn Rust Coding