使用Rust构建API
Rust,API
一般在自己个人项目中我喜欢使用 Rust。用独特的方式结合了速度、安全性和并发性开发强大的API。
可以使用MongoDB或PostgreSQL数据库创建一个CRUDAPI,在这里我使用MySQL数据库来构建相同的功能。
首先设置DOCKER,MySQL后使用SQLx-CLI进行架构迁移,最后创建CRUDAPI控制器,并在服务器上配置CORS允许跨源请求。
设置 Rust API
先设置Rust项目:
创建文件夹:
创建一个名为rust-mysql-api
初始化项目:
在终端中新创建的文件夹并运行命令cargo init初始化Rust二进制项目。
在VSCODE中打开项目:
初始化项目后,在编辑器或集成开发环境中打开文件夹。
安装所需的包:
在代码编辑器中打开集成终端并运行以下命令来安装所有的依赖项。
cargo add axum
cargo add tokio -F full
cargo add tower-http -F "cors"
cargo add serde_json
cargo add serde -F derive
cargo add chrono -F serde
cargo add dotenv
cargo add uuid -F "serde v4"
cargo add sqlx -F "runtime-async-std-native-tls mysql chrono uuid"
Cargo.toml
[package]
name = "rust-l-crud-api"
version = "0.1.0"
edition = "2021"
[dependencies]
axum = "0.7.7"
chrono = { version = "0.4.38", features = ["serde"] }
dotenv = "0.15.0"
serde = { version = "1.0.210", features = ["derive"] }
serde_json = "1.0.128"
sqlx = { version = "0.8.2", features = ["runtime-native-tls", "mysql", "chrono", "uuid"] }
tokio = { version = "1.40.0", features = ["full"] }
tower-http = { version = "0.6.1", features = ["cors"] }
uuid = { version = "1.10.0", features = ["serde", "v4"] }
chrono
– Rust 的日期和时间库dotenv
– 从文件加载环境变量.env
。serde
– 用于序列化和反序列化 Rust 数据结构的框架sqlx
– Rust 的 SQL 工具包tokio
– 使用 Rust 编写异步应用程序的运行时tower-http
– 拥有大量在构建 HTTP 服务器和客户端时非常有用的中间件
在Docker启动MySQL服务器实例,在根目录中创建一个docker-compose.yml文件添加Docker配置:
docker-compose.yml
services:
mysql:
image: mysql:latest
container_name: mysql
env_file:
- ./.env
ports:
- '6500:3306'
volumes:
- mysqlDB:/var/lib/mysql
phpMyAdmin:
image: phpmyadmin
restart: always
container_name: phpMyAdmin
env_file:
- ./.env
environment:
- PMA_HOST=mysql
ports:
- '8080:80'
depends_on:
- mysql
volumes:
mysqlDB:
.env
MYSQL_DATABASE=rust_sqlx
MYSQL_USER=admin
MYSQL_PASSWORD=password123
MYSQL_ROOT_PASSWORD=password123
DATABASE_URL=mysql://${MYSQL_USER}:${MYSQL_PASSWORD}@localhost:6500/${MYSQL_DATABASE}
使用 SQLx 执行数据库迁移
现在 MySQL 数据库已启动并运行,创建必要的表,使用 SQLx-CLI 工具包通过代码完全处理此问题。确保已安装 SQLx-CLI。
可以通过运行以下命令来安装:cargo install sqlx-cli
。
安装 SQLx-CLI 后,运行命令在sqlx migrate add -r init
内生成“up”和“down”迁移脚本migrations
。
打开“up”迁移脚本并包含以下 SQL 语句feedbacks
在数据库中创建表:
CREATE TABLE feedbacks (
id CHAR(36) PRIMARY KEY NOT NULL,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
feedback VARCHAR(500) NOT NULL UNIQUE,
rating FLOAT CHECK (rating >= 1 AND rating <= 5) NOT NULL,
status VARCHAR(50) DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
创建数据库模型
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
#[derive(Debug, Serialize, Deserialize, FromRow)]
pub struct Feedback {
pub id: String,
pub name: String,
pub email: String,
pub feedback: String,
pub rating: i32,
pub status: Option,
pub created_at: Option>,
pub updated_at: Option>,
}
schema.rs
use serde::{Deserialize, Serialize};
pub struct FilterOptions {
pub page: Option,
pub limit: Option,
}
pub struct CreateFeedbackSchema {
pub name: String,
pub email: String,
pub feedback: String,
pub rating: i32,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option,
}
pub struct UpdateFeedbackSchema {
pub name: Option,
pub email: Option,
pub feedback: Option,
pub rating: Option,
pub status: Option,
}
API 路由
use std::sync::Arc;
use axum::{
routing::{get, post},
Router,
};
use crate::{
handlers::{
create_feedback_handler, delete_feedback_handler, edit_feedback_handler, get_feedback_handler,
health_checker_handler, feedback_list_handler,
},
AppState,
};
pub fn create_router(app_state: Arc) -> Router {
Router::new()
.route("/api/healthchecker", get(health_checker_handler))
.route("/api/feedbacks/", post(create_feedback_handler))
.route("/api/feedbacks", get(feedback_list_handler))
.route(
"/api/feedbacks/:id",
get(get_feedback_handler)
.patch(edit_feedback_handler)
.delete(delete_feedback_handler),
)
.with_state(app_state)
}
你的反应是什么?