六 Rust Web入门:服务器端web应用

本教程笔记来自 杨旭老师的 rust web 全栈教程,链接如下:
学习 Rust Web 需要学习 rust 的前置知识可以学习杨旭老师的另一门教程
项目的源代码可以查看 git:(注意作者使用的是 mysql 数据库而不是原教程的数据库)
在之前的项目中,我们已经使用了 rust 编写了一些具有增删改查功能的接口并且进行测试,但是作为一款完整的应用,他还需要将这些数据展示到页面中的功能;在之前的学习中,我们已经尝试过将一个html 页面提供给用户,但是在实际开发中,我们肯定希望我们的数据可以绑定到页面中展示给用户,类似许多语言提供了模板引擎功能,如 jsp、asp 等,rust也有自己的模板引擎 Tera,找不到官网链接了,给一个资料链接:
这节课我们使用 Tera 来完成一个简单的新增教师和查询教师的界面:
架构搭建
同样我们新建一个项目,在开始编写之前我们先添加我们的依赖
[dependencies]actix-files = "0.6.0-beta.16"actix-web = "4.0.0-rc.2"awc = "3.0.0-beta.21"chrono = { version = "0.4.19", features = ["serde"] }dotenv = "0.15.0"# openssl = { version = "0.10.38", features = ["vendored"] }serde = { version = "1.0.136", features = ["derive"] }serde_json = "1.0.79"tera = "1.15.0"
之后我们依次新建 .rs , .rs , .rs 和 .rs 作为我们的各个功能模块,我们编写一个 mod.rs 将各个模块导出:
pub mod errors;pub mod handlers;pub mod routers;pub mod models;
之后在根目录下创建一个文件夹存放我们的模板 html 文件和样式文件等资源,
最后我们在 bin 目录下新建我们的 svr.rs 文件作为我们的启动文件,现在完整的架构搭建起来了
配置服务器
对于这个项目,我们将项目的启动路径编写在配置文件中,方便我们随时改变他,我们在根目录编写一个 .env 文件写上我们的端口:
HOST_PORT = 127.0.0.1:4396
之后我们在 svr.rs 文件编写我们的服务器启动逻辑,我们获取配置文件的服务器启动地址之后,之后我们将文件夹绑定在 tera 中,这样文件夹下的文件就会被 tera 识别到,之后我们将 tera 传入整个项目中,我们的项目就可以使用 tera 这个引擎的相关内容了,最后我们在配置文件的编写的地址启动我们的项目:
#[path = "../mod.rs"]mod wa;use actix_web::{web, App, HttpServer};use dotenv::dotenv;use routers::app_config;use std::env;use wa::{errors,handlers,models,routers};use tera::Tera;#[actix_web::main]async fn main() -> std::io::Result<()> {dotenv().ok();let host_port = env::var("HOST_PORT").expect("HOST_PORT 没有在 .env 文件里设置")HttpServer::new(move || {let tera = Tera::new(concat!(env!("CARGO_MANIFEST_DIR"),"/static/**/*")).unwrap();App::new().app_data(web::Data::new(tera)).configure(app_config)}).bind(&host_port)?.run().await}
业务逻辑

六  Rust Web入门:服务器端web应用

文章插图
现在我们的服务器已经能启动起来了,我们来为他编写业务逻辑:
首先是,我们编写两个数据结构方便我们查询和提交老师的数据:
use serde::{Deserialize, Serialize};#[derive(Deserialize, Serialize, Debug)]pub struct TeacherRegisterForm {pub name: String,pub imageurl: String,pub profile: String,}#[derive(Deserialize, Serialize, Debug)]pub struct TeacherResponse {pub id: i32,pub name: String,pub picture_url: String,pub profile: String,}
之后我们编写来配置我们的路由,我们直接访问页面的时候展示所有老师的信息,而页面用于注册老师,注册信息通过-post 发送,而对静态文件的请求可以返回正确的静态文件 fs::Files::new("/","./")就是将 / 文件夹下的内容作为我们的静态资源列表,当用户请求静态资源的时候,就从这个位置获取他们: