Rocket是一個使用Rust程式語言的Web框架,在伺服器端運行,任何人都可以用它來輕易地開發出高彈性、高可用性以及擁有型別安全特性的Web應用程式。這個系列文章將會帶您一步步了解Rocket框架的使用方法。



Rocket框架

Rocket這個英文單字的意思就是火箭,可能是因為框架的作者任職於SpaceX這間美國航太科技公司,所以才如此命名,還挺酷的。Rocket的目標在於提供一個快速、簡單、彈性且安全的Web框架,而且開發起來會感到愉快,因為它應用了Rust程式語言的「程序式巨集」,來自動產生那些複雜且繁瑣的程式碼。

在您繼續閱讀本系列文章之前,如果您還不熟悉Rust程式語言,請先參考筆者先前撰寫的《Rust學習之路》系列文章,並且詳讀最後一章:建立多執行緒的Web伺服器。如此一來在閱讀本系列文章時,就能更加感到用Rocket來開發Web伺服器是有多麼地輕鬆愉快~

Rocket框架使用純Rust程式語言來打造,不需相依於第三方動態函式庫,可以很容易地移植到各個平台上運行。在性能上,它雖然不能說是Rust家族中最快的Web框架,但也不差。

以下是Rust、Golang、Node.js、PHP的主流Web框架的效能測試結果(測試時間為2019年5月8日,使用的測試工具和腳本可以在此取得):

rocket-introduction

rocket-introduction

從上圖測試結果可以看出來,Rocket的平均反應時間和吞吐量都比其它有被拿來測試的Web框架還要好,只不過這邊提供的是沒有啟用keep-alive機制的測試結果。在現實應用中,使用網頁瀏覽器瀏覽網站時經常會需要透過HTTP的keep-alive連線機制來加速,而Rocket在現階段似乎無法完全正常支援keep-alive的樣子(有一些相容性問題)。所以在部署Rocket的Web應用程式時,最好再加上一個如Nginx的前端伺服器來搭配使用。

雖然Rocket的應用程式容易部署而且效能很好,但它因為有用到Rust程式語言的實驗功能(詳情可查看這個網頁),所以必須要使用Nightly版本的Rust才可以進行編譯,導致Rocket可能比較不那麼適合用在對於API的穩定性需要嚴格要求的場合。

Rocket框架有以下三大宗旨:

  1. 安全、正確、重視開發者體驗。
  2. 所有要交給開發者處理的請求(request)都會被自動型別化,不需要撰寫額外的轉換程式。且每個請求在處理時都是各別獨立的,沒有全域的狀態。
  3. 不會強制一定得使用Rocket提供的模板引擎、序列化、會話(session)等非與處理HTTP協定直接相關的套件,這些套件都是可選的。

Hello World

學習一個Web框架,跟學一個程式語言一樣,依照慣例,第一支程式都會是「Hello World」。現在,我們就來從無到有,一步步地從開新的Cargo程式專案開始,一直到能夠在網頁瀏覽器上印出Hello, world!這幾個字吧!

建立專案目錄

首先,執行以下指令,用Cargo建立出名叫hello_rocket的應用程式專案。

cargo new --bin hello_rocket

然後別忘了將工作目錄也跟著移動到剛才建立出來的應用程式專案的根目錄中,指令如下:

cd hello_rocket

rocket-introduction

Cargo.toml設定檔中加入Rocket

接著編輯Cargo.toml設定檔,在[dependencies]區塊中加入Rocket。我們可以在crates.io上找到Rocket專案。在此以Rocket的0.4版本為例,Cargo.toml設定檔的寫法如下:

[package]
name = "hello_rocket"
version = "0.1.0"
authors = ["Magic Len <len@magiclen.org>"]
edition = "2018"

[dependencies]
rocket = "0.4"

使程式專案預設使用Nightly的Rust來編譯

在Rust程式專案的根目錄中執行以下指令,即可只讓該程式專案使用Nightly的Rust來編譯,而不會去動到其它專案的設定。

rustup override set nightly

rocket-introduction

撰寫程式碼

接著編輯src/main.rs原始碼,內容如下:

#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use]
extern crate rocket;

#[get("/")]
fn index() -> &'static str {
    "Hello, world!"
}

fn main() {
    rocket::ignite().mount("/", routes![index]).launch();
}

以上程式,我們先在第一行宣告了Rocket會使用到的Nightly的Rust所提供的proc_macro_hygienedecl_macro特色。接著於程式第3行到第4行,引用了rocket這個crate,包含其公開出來的巨集。在程式第6行,我們使用了Rocket提供的程序式巨集,使得其後的第7行到第9行的函數index變成請求方法是GET時,且遇到路徑是/時的路由(routing)處理程序(handler)。

main函數中,使用rocket這個crate提供的ignite函數,來快速地產生出一個預設(設定值可透過環境變數或設定檔來讀入)的Rocket結構實體,接著再使用Rocket結構實體的mount方法,將index這個路由處理程序註冊在/根目錄下。也就是說,當有來自客戶端的請求是想要用HTTP的GET來請求「根目錄下的根目錄」(也就是根目錄)時,Rocket就會呼叫index這個路由處理程序來處理該請求。這個mount方法需與routes巨集互相搭配使用。

Rocket結構實體的mount方法會取得結構實體的擁有權,並且在執行後又將Rocket結構實體回傳出來。Rocket結構實體的launch方法,會取得結構實體的擁有權,並且啟動Rocket的HTTP的服務,開始進行監聽。

編譯並執行專案

當程式撰寫完成之後,就可以用以下指令來編譯並執行專案:

cargo run

rocket-introduction

rocket-introduction

檢查成果

在網頁瀏覽器上開啟http://localhost:8000,來看看是否有出現Hello, world!這幾個字!

rocket-introduction

總結

在這一章節中,我們對Rocket這個Web框架有了粗淺的認識,也學會了從無到有,用Rocket來製作出Hello World網頁的方式。

在下一章節中,我們會更深入地探討Rocket的路由和處理請求的方式。

下一章:路由(Routing)與請求(Request)的處理