【一起学Rust | 框架篇 | Anansi框架】万字长文带你入门RustWeb开发



前言

新手学习一门编程语言总是很迷茫的,除了枯燥的语法,还要学习其庞大的生态,如果你不了解生态,那么掌握语法也是空。在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,那么需要完成以下三步

  1. Cargo.toml中将sqlite改成postgres
  2. src/project.rs中修改database!(sqlite)database!(postgres)
  3. 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 用来表示外键约束,表示TopicUser多对一的关系

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-compsmini-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 {
   
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

广龙宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值