واجهات REST البرمجية باستخدام Actix-web/Rocket
طوّروا واجهات RESTful البرمجية باستخدام إطار ويب حديث بلغة Rust مثل Actix-web أو Rocket، مع معالجة المسارات والطلبات والاستجابات.
واجهات REST البرمجية باستخدام Actix-web/Rocket درس مجاني في Learn Rust Coding على CoddyKit. هذا هو الدرس 1 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Learn Rust Coding، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Learn Rust Coding 3 دروس في المجموع.
بعض أجزاء هذا الدرس لم تُترجم بعد وتظهر باللغة الإنجليزية.
What are REST APIs?
REST, or REpresentational State Transfer, is an architectural style for networked applications. It defines a set of principles for how web services should communicate.
Think of it as a set of guidelines for building web services that are stateless, cacheable, and use standard HTTP methods to interact with resources.
- Resources: Anything that can be named, like a user, a product, or an order.
- URIs: Unique identifiers for resources (e.g.,
/users/123). - HTTP Methods: Standard actions performed on resources (GET, POST, PUT, DELETE).
Why Rust for Web Services?
Rust brings unique advantages to web service development, making it a strong choice for high-performance and reliable APIs:
- Performance: Rust's zero-cost abstractions mean highly efficient code, often comparable to C/C++.
- Memory Safety: The ownership system prevents common bugs like null pointer dereferences and data races, leading to more robust services.
- Concurrency: Rust's async/await model, combined with its safety guarantees, makes building concurrent web services 'fearless'.
- Reliability: Strong type system and compile-time checks catch many errors early.
Meet Actix-web
For building web services in Rust, we often use frameworks. Actix-web is a powerful, pragmatic, and extremely fast web framework for Rust.
It's built on top of Actix, an actor framework, but you don't need to understand actors to use Actix-web effectively. It's designed for asynchronous operations, making it ideal for I/O-bound tasks like handling many concurrent API requests.
Actix-web provides tools for routing, request/response handling, middleware, and much more, simplifying the creation of complex APIs.
Project Setup & Dependencies
To start, we'll create a new Rust project and add the necessary dependencies. We'll use actix-web for the framework and serde for serializing/deserializing JSON data.
First, create a new project:
cargo new my_rest_api --bin
Then, add these lines to your Cargo.toml file under the [dependencies] section:
[dependencies]
actix-web = "4"
serde = { version = "1.0", features = ["derive"] }
Your First Actix-web Server
Let's write a minimal Actix-web server. This code sets up the basic structure to listen for incoming HTTP requests on port 8080. It doesn't handle any specific routes yet, but it's the foundation.
The #[actix_web::main] macro makes our async fn main compatible with Actix-web's runtime.
use actix_web::{App, HttpServer};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
println!("Server running at http://127.0.0.1:8080");
HttpServer::new(|| {
// Our application instance, where we'll add routes
App::new()
})
.bind(("127.0.0.1", 8080))? // Bind to an IP address and port
.run() // Start the server
.await // Await its completion
}Defining a GET Route
Now, let's add a simple route to our server. A route maps an incoming HTTP request path and method (like GET /hello) to a specific handler function.
Our handler function hello_world will simply return a string. web::get().to() registers this handler for GET requests to the /hello path.
use actix_web::{web, App, HttpServer, Responder};
// A handler function that returns a simple string response
async fn hello_world() -> impl Responder {
"Hello, Actix-web!"
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
println!("Server running at http://127.0.0.1:8080");
HttpServer::new(|| {
App::new()
// Register our route: GET /hello maps to hello_world()
.route("/hello", web::get().to(hello_world))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}Path Parameters for Dynamic Routes
APIs often need to handle dynamic parts in the URL, like an ID or a name. Actix-web uses path parameters to capture these values.
We define a placeholder in the route (e.g., /{name}). In the handler, we use web::Path<String> (or any other type that can be deserialized) to extract the value.
use actix_web::{web, App, HttpServer, Responder};
// Handler function with a path parameter 'name'
async fn greet_name(name: web::Path<String>) -> impl Responder {
format!("Hello, {}!", name.into_inner())
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
println!("Server running at http://127.0.0.1:8080");
HttpServer::new(|| {
App::new()
// Route with a dynamic path segment for a name
.route("/greet/{name}", web::get().to(greet_name))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}Handling POST Requests & JSON
For creating or updating resources, we use POST or PUT requests, often sending data in the request body as JSON.
Actix-web makes handling JSON easy with web::Json<T>. We define a Rust struct that matches our expected JSON structure, derive Deserialize from serde, and Actix-web automatically parses the incoming JSON into our struct.
use actix_web::{web, App, HttpServer, Responder};
use serde::{Deserialize, Serialize};
// Define a struct to represent our incoming JSON data
#[derive(Deserialize, Serialize)]
struct User {
username: String,
email: String,
}
// Handler for POST requests that accepts a JSON User object
async fn create_user(user: web::Json<User>) -> impl Responder {
// In a real app, you'd save this user to a database
format!("User created: {} ({})", user.username, user.email)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
println!("Server running at http://127.0.0.1:8080");
HttpServer::new(|| {
App::new()
// POST /users expects a JSON body and maps to create_user()
.route("/users", web::post().to(create_user))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}Building a Simple API with State
Let's combine what we've learned to build a small API that manages a list of users in memory. We'll use web::Data to share application-specific state (our user list) across handlers.
std::sync::Mutex is used to safely allow mutable access to our Vec<User> from multiple concurrent requests. We'll have endpoints to GET /users and POST /users.
use actix_web::{web, App, HttpServer, Responder, HttpResponse};
use serde::{Deserialize, Serialize};
use std::sync::Mutex; // For shared mutable state
// Define a User struct that can be serialized/deserialized and cloned
#[derive(Deserialize, Serialize, Clone)]
struct User {
id: u32,
username: String,
email: String,
}
// Application state to hold our users and track next ID
struct AppState {
users: Mutex<Vec<User>>,
next_id: Mutex<u32>,
}
// Handler to get all users
async fn get_users(data: web::Data<AppState>) -> impl Responder {
let users = data.users.lock().unwrap(); // Acquire a lock
web::Json(users.clone()) // Return users as JSON
}
// Handler to create a new user
async fn create_user(
data: web::Data<AppState>,
new_user: web::Json<User>,
) -> impl Responder {
let mut users = data.users.lock().unwrap();
let mut next_id = data.next_id.lock().unwrap();
let user = User {
id: *next_id,
username: new_user.username.clone(),
email: new_user.email.clone(),
};
users.push(user.clone());
*next_id += 1; // Increment for the next user
HttpResponse::Created().json(user) // Return 201 Created status and user
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
println!("Server running at http://127.0.0.1:8080");
// Create shared application state
let app_state = web::Data::new(AppState {
users: Mutex::new(vec![]), // Initialize with an empty user list
next_id: Mutex::new(1), // Start IDs from 1
});
HttpServer::new(move || { // 'move' closure to capture app_state
App::new()
.app_data(app_state.clone()) // Register shared state with the app
.route("/users", web::get().to(get_users))
.route("/users", web::post().to(create_user))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}API Concepts Quick Check
You've learned how to set up a basic Actix-web server and handle different HTTP requests. Let's test your understanding!
Recap & Next Steps
Well done! You've taken your first steps into building RESTful APIs with Rust and Actix-web.
- We explored REST API fundamentals and why Rust is a great fit.
- You learned to set up a basic Actix-web project.
- We covered defining GET and POST routes.
- You saw how to extract path parameters and handle JSON payloads.
- Finally, you built a simple API managing in-memory state using
web::Data.
Next, you'll delve deeper into database integration and robust error handling to build even more powerful and production-ready web services!
الأسئلة الشائعة
هل درس «واجهات REST البرمجية باستخدام Actix-web/Rocket» مجاني؟
نعم — نص درس «واجهات REST البرمجية باستخدام Actix-web/Rocket» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Learn Rust Coding، انتقل إلى CoddyKit PRO. تتضمن دورة Learn Rust Coding 3 دروس في المجموع.
ماذا ستتعلم في «واجهات REST البرمجية باستخدام Actix-web/Rocket»؟
طوّروا واجهات RESTful البرمجية باستخدام إطار ويب حديث بلغة Rust مثل Actix-web أو Rocket، مع معالجة المسارات والطلبات والاستجابات. تتمرن على Learn Rust Coding مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Learn Rust Coding؟
لا تُشترط خبرة سابقة. Learn Rust Coding على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 3.
كم من الوقت يستغرق درس «واجهات REST البرمجية باستخدام Actix-web/Rocket»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Learn Rust Coding هذا؟
نعم. كل درس في Learn Rust Coding يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- واجهات REST البرمجية باستخدام Actix-web/Rocket
- تكامل قواعد البيانات (SQLx/Diesel)
- المصادقة والتفويض