1

使用Rust+Rocket创建一个CRUD的RESTful歌曲请求API

 1 year ago
source link: https://www.jdon.com/63079
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

使用Rust+Rocket创建一个CRUD的RESTful歌曲请求API


如果您在 YouTube 和 Twitch 等平台上观看流媒体,您可能遇到过歌曲请求系统。歌曲请求系统允许观众将歌曲添加到 歌曲队列中。当歌曲到达队列的最前面时,歌曲会在直播流中播放。
在 Rocket crate 的帮助下,Rust 为这个系统创建一个 API 非常容易。
使用Rocket箱创建一个 RESTful API。

初始化:

cargo init <YOUR_PROJECT_NAME>

加入依赖:

[dependencies]

# NOTE: This is a pre-release version.
# Thus, It is suggested NOT to use this in production.
rocket = "0.5.0-rc.2"

在我们的Cargo项目准备就绪后,我们可以完全删除默认的主函数。这将为我们的新rocket方法腾出空间,该方法归属于Rocket的发射程序宏。

这个函数实质上将取代我们的主函数,并在启动时被调用。

//main.rs

#[macro_use]
extern crate rocket;

use rocket::{Build, Rocket};

#[launch]
fn rocket() -> Rocket<Build> {
    Rocket::build()
        // 设置`/`路由路径作为我们路由的基础。
        // 当我们创建我们的路由时,我们将把它们包括在`routes!`宏的参数中。
        .mount("/", routes![])
}

运行后输出:

Configured for debug.
   >> address: 127.0.0.1
   >> port: 8000
   >> workers: 6
   >> ident: Rocket
   >> limits: bytes = 8KiB, data-form = 2MiB, file = 1MiB, form = 32KiB, json = 1MiB, msgpack = 1MiB, string = 8KiB
   >> temp dir: C:\Users\dev\AppData\Local\Temp\
   >> http/2: true
   >> keep-alive: 5s
   >> tls: disabled
   >> shutdown: ctrlc = true, force = true, grace = 2s, mercy = 3s
   >> log level: normal
   >> cli colors: true
Fairings:
   >> Shield (liftoff, response, singleton)
Shield:
   >> X-Content-Type-Options: nosniff
   >> Permissions-Policy: interest-cohort=()
   >> X-Frame-Options: SAMEORIGIN
Rocket has launched from http://127.0.0.1:8000

现在我们有了我们的rocket函数,我们可以开始为我们的API开发功能。

储存歌曲队列
为了存储歌曲队列,我们将使用一个静态的LinkedList。
我们使用LinkedList是因为它包含在标准库中,并且基本上是作为一个具有额外功能的队列。

不过,为了允许静态地修改列表,我们必须用Mutex来包装这个列表。

use std::collections::LinkedList;
use std::sync::Mutex;

static SONG_QUEUE: Mutex<LinkedList<String>> = Mutex::new(LinkedList::new());

更多Mutex, click here.(中文:https://github.com/kumakichi/easy_rust_chs)

我们将多次重复以下代码:

let lock = SONG_QUEUE
    .lock()
    .expect("Unable to acquire lock on song queue because the Mutex was poisoned");

如果我们创建一个为我们执行此操作的函数会更好。

use std::sync::{Mutex, MutexGuard};

fn acquire_queue<'a>() -> MutexGuard<'a, LinkedList<String>> {
    SONG_QUEUE
        .lock()
        .expect("Unable to acquire lock on song queue because the Mutex was poisoned")
}

创建add路由
SONG_QUEUE定义好变量后,我们就可以开始创建路由了。
该add路由将收到一个包含歌曲名称的POST请求,然后将其添加到歌曲队列中。
或者,我们可以返回歌曲所在的位置。

#[post("/add/<song_name>")]
fn add_song(song_name: String) -> String {
    let mut lock = acquire_queue();

    lock.push_back(song_name);

    format!("Song added. This song is in position {}.", lock.len())
}

不要忘记在routes!宏中注册这个新路由。

  1. - .mount("/", routes![])
  2. + .mount("/", routes![add_song])

测试:

C:\Users\dev>curl -X POST http://localhost:8000/add/Hello
Song added. This song is in position 1.
C:\Users\dev>curl -X POST http://localhost:8000/add/Hello%20number%202
Song added. This song is in position 2.

创建view路由
用户现在可以添加歌曲,但无法查看当前在队列中的歌曲。
别担心,我们将创建一个新的GET路由。

只有一行代码!

#[get("/view")]
fn view() -> String {
    format!("{:?}", acquire_queue())
}

不要忘记在routes!宏中注册这个新路由。

  1. - .mount("/", routes![add_song])
  2. + .mount("/", routes![add_song, view])

运行:

C:\Users\dev>curl -X POST http://localhost:8000/add/Hello%20World
Song added. This song is in position 1.

C:\Users\dev>curl http://localhost:8000/view
<p class="indent">["Hello World"]

删除歌曲
为了文章的简单起见,一旦歌曲到达队列的最前面,我们将不会真正播放它们。相反,我们只会在经过一定时间后删除歌曲。
在这种情况下,我们会在歌曲排到队列前 60 秒后移除歌曲

use std::thread;
use std::time::Duration;

fn remove_song_timer() {
    while !acquire_queue().is_empty() {
        thread::sleep(Duration::from_secs(60));
        acquire_queue().pop_front();
    }
}

我们需要修改我们的add_song路由以确保在remove_song_timer将歌曲添加到空队列时生成线程。

#[post("/add/<song_name>")]
fn add_song(song_name: String) -> String {
    let mut lock = acquire_queue();

    if lock.is_empty() {
        thread::spawn(remove_song_timer);
    }
    lock.push_back(song_name);

    format!("Song added. This song is in position {}.", lock.len())
}

结果:

C:\Users\dev>curl -X POST http://localhost:8000/add/Hello%20World
Song added. This song is in position 1.
C:\Users\dev>curl http://localhost:8000/view
<p class="indent">["Hello World"]

60秒后……

C:\Users\dev>curl http://localhost:8000/view
<p class="indent">[]

 


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK