Rocket是一個使用Rust程式語言的Web框架,在伺服器端運行,任何人都可以用它來輕易地開發出高彈性、高可用性以及擁有型別安全特性的Web應用程式。這個系列文章將會帶您一步步了解Rocket框架的使用方法。
Rocket框架
Rocket這個英文單字的意思就是火箭,可能是因為框架的作者任職於SpaceX這間美國航太科技公司,所以才如此命名,還挺酷的。Rocket的目標在於提供一個快速、簡單、彈性且安全的Web框架,而且開發起來會感到愉快,因為它應用了Rust程式語言的「程序式巨集」,來自動產生那些複雜且繁瑣的程式碼。
在您繼續閱讀本系列文章之前,如果您還不熟悉Rust程式語言,請先參考筆者先前撰寫的《Rust學習之路》系列文章,並且詳讀最後一章:建立多執行緒的Web伺服器。另外還有《用「async / .await」撰寫 Rust 並發程式》一文。如此一來在閱讀本系列文章時,就能更加感到用Rocket來開發Web伺服器是有多麼地輕鬆愉快~
Rocket框架使用純Rust程式語言來打造,不需相依於第三方動態函式庫,可以很容易地移植到各個平台上運行。在性能上,它是Rust家族中雖然表現普通,但與JavaScript的Web框架相比已是快了不少。
Rocket框架有以下三大宗旨:
- 安全、正確、重視開發者體驗。
- 所有要交給開發者處理的請求(request)都會被自動型別化,不需要撰寫額外的轉換程式。且每個請求在處理時都是各別獨立的,沒有全域的狀態。
- 不會強制一定得使用Rocket提供的模板引擎、序列化、會話(session)等非與處理HTTP協定直接相關的套件,這些套件都是可選的。
Hello World
學習一個Web框架,跟學一個程式語言一樣,依照慣例,第一支程式都會是「Hello World」。現在,我們就來從無到有,一步步地從開新的Cargo程式專案開始,一直到能夠在網頁瀏覽器上印出Hello, world!
這幾個字吧!
建立專案目錄
首先,執行以下指令,用Cargo
建立出名叫hello_rocket
的應用程式專案。
在Cargo.toml
設定檔中加入Rocket
接著編輯Cargo.toml
設定檔,在[dependencies]
區塊中加入Rocket。我們可以在crates.io上找到Rocket專案。在此以Rocket的v0.5.0
版本為例,Cargo.toml
設定檔的寫法如下:
[package]
name = "hello_rocket"
version = "0.1.0"
edition = "2021"
[dependencies]
rocket = "0.5.0"
撰寫程式碼
接著編輯src/main.rs
原始碼,內容如下:
#[macro_use]
extern crate rocket;
#[get("/")]
fn index() -> &'static str {
"Hello, world!"
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![index])
}
以上程式,我們先用#[macro_use]
屬性和extern crate
關鍵字來引用rocket
這個crate公開出來的所有巨集。在程式第4行,我們使用了Rocket提供的程序式巨集,使得其後的第5行到第7行的index
函數成為當HTTP請求的方法(method)是GET
時,且請求路徑是/
時的路由(routing)處理程序(handler)。
rocket
函數必須搭配rocket
提供的launch
程序式巨集來使用,且必須回傳一個Rocket結構實體。在rocket
函數中,使用rocket
這個crate提供的build
函數,來快速地產生出一個預設(設定值可透過環境變數或設定檔來讀入)的Rocket
結構實體,接著再使用Rocket
結構實體的mount
方法,將index
這個路由處理程序註冊在/
根目錄下。也就是說,當有來自客戶端的請求是想要用HTTP的GET
來請求「根目錄下的根目錄」(也就是根目錄)時,Rocket就會呼叫index
這個路由處理程序來處理該請求。這個mount
方法需與rocket
的routes!
巨集互相搭配使用。
Rocket
結構實體的mount
方法會取得結構實體的擁有權,並且在執行後又將Rocket
結構實體回傳出來。在rocket
函數的最後回傳Rocket
結構實體。
編譯並執行專案
當程式撰寫完成之後,就可以用以下指令來編譯並執行專案:
檢查成果
在網頁瀏覽器上開啟http://localhost:8000
,來看看是否有出現Hello, world!
這幾個字!
程式進入點
Rocket幫提供了極為簡易的方式處理程式進入點,也就是上面介紹的#[launch]
屬性和rocket
函數,但如果我們想要替我們的程式製作命令列介面(CLI)的話,就得自行實作傳統main
函數作為程式進入點了。
要在main
函數中執行Rocket,main
函數可以這樣寫:
#[macro_use]
extern crate rocket;
use std::error::Error;
#[get("/")]
fn index() -> &'static str {
"Hello, world!"
}
#[rocket::main]
async fn main() -> Result<(), Box<dyn Error>> {
rocket::build().mount("/", routes![index]).launch().await?;
Ok(())
}
我們必須自行使用Rocket
結構實體的launch
方法來啟動Rocket伺服器。
如果我們不想要一開始就使用非同步的main
函數,還可以將以上程式改寫如下:
#[macro_use]
extern crate rocket;
use std::error::Error;
#[get("/")]
fn index() -> &'static str {
"Hello, world!"
}
fn main() -> Result<(), Box<dyn Error>> {
let app = rocket::build().mount("/", routes![index]);
rocket::execute(async move { app.launch().await })?;
Ok(())
}
呼叫rocket
自帶的execute
函數可以建立Rocket專用的非同步執行環境。
總結
在這一章節中,我們對Rocket這個Web框架有了粗淺的認識,也學會了從無到有,用Rocket來製作出Hello World網頁的方式。
在下一章節中,我們會更深入地探討Rocket的路由和處理請求的方式。
下一章:路由(Routing)與請求(Request)的處理。