Rust项目搭建
1、认识搭建
在Rust生态系统中,Actix-web、Rocket和Axum都是非常流行的Web框架,接下来我们就Actix-web来搭建一个框架,简单实现项目的接口调用
👉相关版本地址
javascript
// 安装地址
https://doc.rust-lang.org/stable/releases.html#version-1870-2025-04-03
//更新命令
rustup update stable
👉 搭建项目(版本1.87.0)
这里我们再来看看之前我们搭建运行以及打包的相关命令
javascript
//创建项目
cargo new nexusrust
cd nexusrust
//运行项目
cargo run
//打包项目
cargo build
// 测试项目
cargo test
👉 目录结构
首先我们来看看项目工程目录结构
rust
nexusrust/
├── Cargo.toml # Rust项目的配置文件,定义了项目的依赖和构建脚本
├── src/
│ ├── main.rs # 项目的入口文件,通常包含程序的启动逻辑
│ ├── config/ # 配置文件和配置相关的模块
│ │ └── mod.rs # 配置模块的主文件,用于初始化和加载配置
│ ├── modules/ # 数据模型定义
│ │ ├── mod.rs # 数据模型模块的主文件,定义了项目中使用的数据结构
│ │ ├── user.rs # 用户模型定义
│ │ ├── article.rs # 文章模型定义
│ │ └── role.rs # 角色模型定义
│ ├── routes/ # 路由处理
│ │ ├── mod.rs # 路由模块的主文件,定义了API的路由和请求处理函数
│ │ ├── user.rs # 用户相关的路由
│ │ ├── article.rs # 文章相关的路由
│ │ └── role.rs # 角色相关的路由
│ ├── handlers/ # 请求处理函数
│ │ ├── mod.rs # 请求处理模块的主文件,包含处理HTTP请求的函数
│ │ ├── user.rs # 用户相关的处理函数
│ │ ├── article.rs # 文章相关的处理函数
│ │ └── role.rs # 角色相关的处理函数
│ ├── database/ # 数据库相关的代码
│ │ └── mod.rs # 数据库模块的主文件,用于数据库连接和操作
│ ├── middlewares/ # 中间件
│ │ └── mod.rs # 中间件模块的主文件,定义了中间件逻辑
│ ├── utils/ # 工具和辅助函数
│ │ └── mod.rs # 工具模块的主文件,包含一些通用的工具函数
│ ├── errors/ # 错误处理
│ │ └── mod.rs # 错误处理模块的主文件,定义了自定义错误类型和错误处理逻辑
│ └── tests/ # 测试代码
│ ├── mod.rs # 测试模块的主文件,包含项目的测试用例
│ ├── user.rs # 用户相关的测试
│ ├── article.rs # 文章相关的测试
│ └── role.rs # 角色相关的测试
└── .env # 环境变量文件,用于存储敏感信息,如数据库凭证
👉Visual Studio Code工具使用
javascript
// 安转扩展rust-analyzer
rust-analyzer
// 安装CodeLLDB 扩展 用于调试
CodeLLDB
安装方式在扩展搜即可
🍎使用 Cargo(Rust 的包管理工具)
javascript
https://crates.io
2、actix-web使用
👉Cargo.toml添加对应的actix-web依赖
javascript
[package]
name = "nexusrust"
version = "0.1.0"
edition = "2024"
[dependencies]
=>
[package]
name = "nexusrust"
version = "0.1.0"
edition = "2024"
[dependencies]
actix-web = "4.0"
// 采取这个最新版本 对应rustc版本为 1.87.0
[dependencies]
actix-web = { version = "4.5.0" }
👉main.rs 文件之中开发接口服务
javascript
use actix_web::HttpResponse;
use actix_web::{App, HttpServer};
async fn index() -> HttpResponse {
HttpResponse::Ok().body("Hello我是太白新开发的Rust")
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().route("/", actix_web::web::get().to(index)))
.bind("127.0.0.1:8080")?
.run()
.await
}
这里我们可以简单看一下上面的文件之中一些rust的写法和用法
javascript
use actix_web::HttpResponse; // 创建命名空间
use actix_web::{App, HttpServer};
// 作用
App用于定义和配置 Web 应用的路由和处理逻辑。
HttpServer模块,用于启动和运行 HTTP 服务器
#[actix_web::main] // 使用 #[actix_web::main] 宏指定 main 函数:
async fn main() -> std::io::Result<()>
// ↑ 定义一个异步函数 main,返回一个std::io::Result<()>类型结果
HttpServer::new() // 创建一个新的 HTTP 服务器实例的方法
|| App::new().route("/", actix_web::web::get().to(index))
// ↑ 闭包(匿名函数),它返回一个新的 App 实例
.route("/", actix_web::web::get().to(index)) 定义了一个路由:
//路由路径为 /
//请求方法为 GET
// 处理函数为 index
↑ 也就是直接调用我们上面的index方法
.bind("127.0.0.1:8080")?
// 运行HttpServer实例
.run()
// 等待HttpServer实例运行完毕
.await
↑ 然后最后进行绑定 运行 以及等待启动
👉重新构建运行项目
javascript
cargo clean //清除
cargo build //构建
cargo run //运行
这个时候访问项目地址
javascript
http://127.0.0.1:8080/
// 出现的提示已经是我们想要的了
Hello鎴戞槸澶櫧鏂板紑鍙戠殑Rust
🍎项目之中有个提示,就是项目的编辑器过高,这里我是希望可以升级项目的版本,但是运行什么的我发现都不受影响。
javascript
mismatched ABI expected: `rustc 1.85.0 (4d91de4e4 2025-02-17)`,
got `rustc 1.87.0 (17067e9ac 2025-05-09)`
3、简单接口的模拟使用
👉配置Cargo.toml
设置依赖
javascript
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
设置跨域
javascript
actix-cors = "0.6"
👉 在根目录下新建一个mod.rs,暴露模块modules
javascript
// src/mod.rs
pub mod modules;
👉 modules模块下新建一个mod.rs,暴露用户
javascript
pub mod user;
👉 modules下建一个user.rs用户模块
在这里我们进行一些简单的数据和接口模拟
javascript
// user.rs
use actix_web::{web, HttpResponse, Responder};
use serde::{Serialize, Deserialize};
use std::sync::{Mutex, Arc};
use std::collections::HashMap;
#[derive(Serialize, Deserialize)]
pub struct User {
pub id: u32,
pub name: String,
pub email: String,
}
type Users = Arc<Mutex<HashMap<u32, User>>>;
pub fn create_users() -> Users {
let users: HashMap<u32, User> = HashMap::new();
Arc::new(Mutex::new(users))
}
pub async fn create_user(users: web::Data<Users>, user: web::Json<User>) -> impl Responder {
let mut users = users.lock().unwrap();
users.insert(user.id, user.into_inner());
HttpResponse::Ok().body("User created")
}
pub async fn get_user(users: web::Data<Users>, user_id: web::Path<u32>) -> impl Responder {
let users = users.lock().unwrap();
if let Some(user) = users.get(&user_id) {
HttpResponse::Ok().json(user)
} else {
HttpResponse::NotFound().body("User not found")
}
}
pub async fn update_user(users: web::Data<Users>, user_id: web::Path<u32>, user: web::Json<User>) -> impl Responder {
let mut users = users.lock().unwrap();
if users.contains_key(&user_id) {
users.insert(user_id.into_inner(), user.into_inner());
HttpResponse::Ok().body("User updated")
} else {
HttpResponse::NotFound().body("User not found")
}
}
pub async fn delete_user(users: web::Data<Users>, user_id: web::Path<u32>) -> impl Responder {
let mut users = users.lock().unwrap();
if users.remove(&user_id).is_some() {
HttpResponse::Ok().body("User deleted")
} else {
HttpResponse::NotFound().body("User not found")
}
}
👉在main.rs中引入
javascript
use actix_web::HttpResponse;
use actix_web::{web,App, HttpServer};
mod modules;
async fn index() -> HttpResponse {
HttpResponse::Ok().body("Hello我是太白新开发的Rust")
}
#[actix_web::main]
// 异步函数main,返回std::io::Result<()>类型
async fn main() -> std::io::Result<()> {
let users = modules::user::create_users(); // 创建用户
HttpServer::new(move|| {
App::new()
.app_data(web::Data::new(users.clone())) // 将用户数据传递给App实例
.route("/", actix_web::web::get().to(modules::user::create_user))
.route("/users", web::post().to(modules::user::get_user))
.route("/users/{id}", web::get().to(modules::user::update_user))
.route("/users/{id}", web::delete().to(modules::user::delete_user))
})
// 绑定到本地的8080端口
.bind("127.0.0.1:8080")?
// 运行HttpServer实例
.run()
// 等待HttpServer实例运行完毕
.await
}
👉配置上接口跨域
javascript
use actix_cors::Cors; // 引入跨域模块
use actix_web::{web,App, HttpServer, HttpResponse}; // 引入actix-web模块
// use actix_files::Files;
mod modules;
async fn index() -> HttpResponse {
HttpResponse::Ok().body("Hello我是太白新开发的Rust")
}
#[actix_web::main]
// 异步函数main,返回std::io::Result<()>类型
async fn main() -> std::io::Result<()> {
let users = modules::user::create_users(); // 创建用户
HttpServer::new(move|| {
let cors = Cors::default()
.allow_any_origin() // 允许任何来源
.allow_any_method() // 允许任何方法
.allow_any_header(); // 允许任何头部
App::new()
.wrap(cors) // 应用 CORS 中间件
.app_data(web::Data::new(users.clone())) // 将用户数据传递给App实例
.route("/", actix_web::web::get().to(modules::user::create_user))
.route("/users", web::post().to(modules::user::get_user))
.route("/users/{id}", web::get().to(modules::user::update_user))
.route("/users/{id}", web::delete().to(modules::user::delete_user))
})
// 绑定到本地的8080端口
.bind("127.0.0.1:8080")?
// 运行HttpServer实例
.run()
// 等待HttpServer实例运行完毕
.await
}
👉 模拟用户查询所有接口
🍎user.rs里面我们模拟用户查询所有的接口
javascript
pub async fn get_all_users() -> impl Responder {
let users = vec![
User {
id: 1,
name: "太白".to_string(),
phone: "18735797974".to_string()
},
];
HttpResponse::Ok().json(users)
}
🍎main.rs 里面调用
javascript
use actix_cors::Cors; // 引入跨域模块
use actix_web::{web,App, HttpServer, HttpResponse}; // 引入actix-web模块
mod modules;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let users = modules::user::create_users(); // 创建用户
HttpServer::new(move|| {
let cors = Cors::default()
.allow_any_origin() // 允许任何来源
.allow_any_method() // 允许任何方法
.allow_any_header(); // 允许任何头部
App::new()
.wrap(cors) // 应用 CORS 中间件
.app_data(web::Data::new(users.clone())) // 将用户数据传递给App实例
.route("/users", web::get().to(modules::user::get_all_users))
})
// 绑定到本地的8080端口
.bind("127.0.0.1:8080")?
.run()
.await
}
🍎测试接口
这里你可以使用一切测试工具,或者直接浏览器打开,切记先重启我们的rust服务
javascript
cargo run
// 重新运行
//访问地址
http://127.0.0.1:8080/users
//回馈给我们的信息
[{"id":1,"name":"太白","email":"18735797974"}]
接下来我们就可以连接数据库,进行我们的API服务开发了,这里我选择的是Mysql 5.8 的版本