文章目录
前言
新手学习一门编程语言总是很迷茫的,除了枯燥的语法,还要学习其庞大的生态,如果你不了解生态,那么掌握语法也是空。在Rust中,也有着跟其他语言一样的Web开发生态,但是基本上都是一言难尽。如果你对rust比较关注,那么你至少应该了解过Axum,Rocket,Actix-web三座大山,但是rust学习曲线陡峭,我认为新手尤其是国内开发者并不适合使用这些,本来语法就难,还要被各种概念卷的晕头转向,我更推荐Salvo(赛风),功能全,文档也丰富,更加适合中国开发者。本文介绍的是一个设计理念跟Django差不多的轻量化Web开发框架,虽然小众,但是五脏俱全,可快速开发出简单的web应用。
Anansi是一个使用Rust写的简单MVC的web框架,在我的使用体验中,我更加觉得这个框架就是Rust版的Django,如果你有Django开发经验,那么将会非常轻而易举的上手开发安全又高性能的web应用,如果你没有Django开发经验,那么也不要慌,跟着本文做完这个小demo,基本上可以用rust做出你想象中的那个应用。
让我们现在就开始入门学习他吧。
一、安装
首先执行以下命令安装Anansi
cargo install ananc
执行以后会自动将依赖等都安装好,就是下图的样子。
查看Anansi的版本,如果返回版本号,说明你已经安装成功,运行正确的结果如下图所示
ananc --version
二、入门案例
注意:本段内容为官网原文翻译
1.创建一个基础的网站
确保你的版本与我一致,然后创建一个项目
ananc new mini-forum
这个代码将会创建一个名字为mini-forum
的项目,其中包含以下必要文件
http_errors/
- http错误处理页面main.rs
- 应用和集合project.rs
- 项目设置urls.rs
- 管理路由
从以上文件可以看出这个web框架其实就是mvc的老三样。
注意:Anansi默认自带一个Sqlite数据库,如果你想要使用PostgreSQL,那么需要完成以下三步
- 在
Cargo.toml
中将sqlite
改成postgres
- 在
src/project.rs
中修改database!(sqlite)
为database!(postgres)
- 在
settings.toml
将[databases.default]
部分修改成以下代码
name = "mydatabase"
user = "myuser"
password = "mypassword"
address = "127.0.0.1:5432"
2.启动web服务器
启动web服务器非常简单,只需要cmd切换到mini-forum/
目录,然后运行以下命令即可
ananc run
如果运行没有任何错误,直接访问http://127.0.0.1:9090/
即可看到创建的网站了。
官方项目git: https://github.com/saru-tora/mini-forum
3.创建一个应用
这块内容用过Django的都熟悉,应该能轻松理解,你只需要知道一个web由多个应用组成就行了。
运行以下命令来创建一个应用,以名字forum
为例
ananc app forum
然后你就会看到创建了一个forum
目录,其中有以下文件
.
├── migrations
├── mod.rs
├── records.rs
└── urls.rs
这些文件的功能你跟着教程走下去就知道是做什么的了。
接下来在main.rs
中包含启用这个应用
mod forum;
apps! {
auth,
sessions,
forum,
}
4.定义记录结构
在forum
目录应该能看到文件records.rs
,这个就是记录,也就是数据库中的记录,首先定义记录结构,
等同于Entity
use anansi::records::{
VarChar, DateTime, ForeignKey};
use anansi::util::auth::records::User;
#[record]
#[derive(Relate, FromParams)]
pub struct Topic {
pub title: VarChar<200>,
pub user: ForeignKey<User>,
pub content: VarChar<40000>,
pub date: DateTime,
}
#[record]
#[derive(Relate, FromParams)]
pub struct Comment {
pub topic: ForeignKey<Topic>,
pub user: ForeignKey<User>,
pub content: VarChar<40000>,
pub date: DateTime,
}
#[record]
会默认添加一个id字段,并且像topic::date
这种字段就可以使用order_by
来查询数据库。Relate
表现的是实体之间的关系FromParams
将允许你从请求的参数中获取记录,也就是反序列化ForeignKey
用来表示外键约束,表示Topic
和User
有多对一
的关系
5.迁移数据库
在定义好记录结构后,即可生成迁移文件,同步到数据库,首先是第一步生成迁移文件
ananc make-migrations forum/
如果你想要查看本次迁移的SQL,那么就执行以下命令
ananc sql-migrate forum 0001
输出将会根据你所选的数据库所生成SQL,如果你使用的是postgresql,那么就会看到以下代码
CREATE TABLE "forum_topic" (
"id" bigint NOT NULL PRIMARY KEY,
"title" varchar(200) NOT NULL,
"user" bigint NOT NULL
REFERENCES "auth_user" ("id")
ON DELETE CASCADE
DEFERRABLE INITIALLY DEFERRED,
"content" varchar(40000) NOT NULL,
"date" timestamp NOT NULL
);
CREATE INDEX "forum_topic_user_index" ON "forum_topic" ("user");
--snip--
CREATE TABLE "forum_comment" (
"id" bigint NOT NULL PRIMARY KEY,
"topic" bigint NOT NULL
REFERENCES "forum_topic" ("id")
ON DELETE CASCADE
DEFERRABLE INITIALLY DEFERRED,
"user" bigint NOT NULL
REFERENCES "auth_user" ("id")
ON DELETE CASCADE
DEFERRABLE INITIALLY DEFERRED,
"content" varchar(40000) NOT NULL,
"date" timestamp NOT NULL
);
CREATE INDEX "forum_comment_topic_index" ON "forum_comment" ("topic");
CREATE INDEX "forum_comment_user_index" ON "forum_comment" ("user");
--略--
接下来应用迁移,执行
ananc migrate
6.前端渲染记录
首先可以先生成前端文件,切到forum
目录,然后运行
ananc make-view topic
就会生成forum/topic/views.rs
文件,进行编辑
use super::super::records::{
Topic, topic::date};
#[viewer]
impl<R: Request> TopicView<R> {
#[view(Site::is_visitor)]
pub async fn index(req: &mut R) -> Result<Response> {
let title = "Latest Topics";
let topics = Topic::order_by(date().desc())
.limit(25).query(req).await?;
}
}
Site::is_visitor
将会校验是否是游客,如果是游客,也就是访问时,那么就会将"Latest Topics"赋值给变量title,然后再将最新的25个topic赋值给变量topics
接下来渲染这些变量到前端,打开forum/topic/templates/index.rs.html
,进行如下改动
@block title {@title}
@block content {
<h1>@title</h1>
<ul>
@for topic in topics {
<li>@topic.title</li>
}
</ul>
}
可以看到这种一种简单的模板语法,使用@
来格式化变量成字符串,读者可以自行体会。
然后添加路由,打开urls.rs
文件添加以下内容
use crate::forum::{
self, topic::views::TopicView};
pub fn routes<R: Request>() -> Router<R> {
Router::new()
.route("", TopicView::index)
.nest("/topic", forum::urls::routes()) // 添加
}
此时你可以打开http://127.0.0.1:9090/
,然而并不会看到任何topic,一个因为数据库本来就没有数据,一个是因为你需要加访问的路径,例如http://127.0.0.1:9090/topic
7. 使用组件
组件是用来做网页的交互的,其中真义只有跟着做下去才知道。
首先还是安装环境,进入项目根目录,也就是mini-forum/
下,运行命令
ananc init-components
This will create the mini-forum-comps and mini-forum-wasm crates. In mini-forum-comps/Cargo.toml, add the following dependency:
这个操作将会创建mini-forum-comps
和mini-forum-wasm
包,在mini-forum-comps/Cargo.toml
中添加以下依赖
gloo-net = {
version = "0.2", features = ["http", "json"] }
不建议随便更新版本,因为会出现无法预料的问题,rust就是这样的。
然后创建mini-forum-comps/src/loader.rs
,并写入以下内容
use anansi_aux::prelude::*;
use gloo_net::http::Request;
#[derive(Properties, Serialize, Deserialize)]
pub struct LoaderProps {
pub load_url: String,
pub show_url: String,
}
#[derive(Serialize, Deserialize)]
pub struct Data {
pub id: String,
pub title: String,
}
#[store]
#[derive(Serialize, Deserialize)]
pub struct Loader {
visible: bool,
page: u32,
fetched: Vec<Data>,
}
#[component(Loader)]
fn init(props: LoaderProps) -> Rsx {