使用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!宏中註冊這個新路由。
- - .mount("/", routes![])
- + .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!宏中註冊這個新路由。
- - .mount("/", routes![add_song])
- + .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">[] |
相關文章
- 使用Golang建立RESTful API的最佳實踐案例GolangRESTAPI
- 使用 Python 構建一個簡單的 RESTful APIPythonRESTAPI
- gin+gorm+router 快速搭建 crud restful API 介面GoORMRESTAPI
- 分享一個大模型在請求api介面上的巧用大模型API
- 實現一個簡單的 RESTful APIRESTAPI
- .NET Core使用 CancellationToken 取消API請求API
- Go語言RESTful JSON API建立GoRESTJSONAPI
- 使用Kotlin + Jersey + Jetty + MongoDB建立可擴充套件的RESTful API - AndrewKotlinJettyMongoDB套件RESTAPI
- MybatisPlus 中的API 使用總結(CRUD)MyBatisAPI
- RESTFUL風格的URL請求及引數接收REST
- 取消Fetch API請求API
- SpringBoot整合Redis使用Restful風格實現CRUD功能Spring BootRedisREST
- laravel 前端有?id=12這麼一個api請求,請教路由怎麼寫Laravel前端API路由
- 無需程式設計,通過配置零程式碼生成CRUD RESTful API程式設計RESTAPI
- php請求API介面方法PHPAPI
- $request 請求方法 獲取 API 的當前使用者API
- 如何在生產環境中通過Restful API的方式請求重啟Spring Boot應用?RESTAPISpring Boot
- .Net Core使用HttpClient請求Web API注意事項HTTPclientWebAPI
- LocustHttp 請求任務建立HTTP
- 用 Go 快速開發一個 RESTful API 服務GoRESTAPI
- 如何高效定義和驗證restful請求的引數REST
- 一文搞懂RESTful APIRESTAPI
- 使用“純”Servlet做一個單表的CRUD操作Servlet
- [Flutter]請求阿里百川的APIFlutter阿里API
- 使用charles嗅探https請求,你的API並不安全HTTPAPI
- SpringBoot:使用AOP對API請求授權驗證 - GeorgeSpring BootAPI
- POS請求API介面樣例API
- 一個很酷的 Vue3 的請求庫Vue
- 介紹一個請求庫 — Undici
- nginx 如何處理一個請求Nginx
- 多個請求統一更新介面
- restful風格請求,基於token鑑權例項REST
- 如何使用 ThinkJS 優雅的編寫 RESTful APIJSRESTAPI
- 使用冪等性抑制API服務中的重複請求 - tkareineAPI
- 使用請求頭認證來測試需要授權的 API 介面API
- 使用 swoole 加速 Larave Restful API 介面(1)RESTAPI
- 使用Golang和MongoDB構建 RESTful APIGolangMongoDBRESTAPI
- Vue 使用 Axios 傳送請求的請求體問題VueiOS