เริ่มต้นด้วยตัวอย่างและคำแนะนำบนเว็บไซต์ของเรา!
ไม่มีเวลาอ่านเอกสาร? ตรวจสอบ
✅ทำงานในเสถียร✅ทำงานเร็ว✅ไม่ได้ใช้ไม่ปลอดภัย
เอกสาร
Thruster เป็นเฟรมเวิร์กเว็บที่มีจุดมุ่งหมายเพื่อให้นักพัฒนามีประสิทธิผลและสอดคล้องกันในโครงการและทีมงาน เป้าหมายคือ:
Thruster ยัง
unsafeThruster สามารถเรียกใช้กับแบ็กเอนด์เซิร์ฟเวอร์ที่แตกต่างกันและแสดงถึงเลเยอร์ที่บรรจุอยู่เหนือพวกเขา ซึ่งหมายความว่ามันสามารถติดตามการเปลี่ยนแปลงล่าสุดและยิ่งใหญ่ที่สุดจากไลค์ของ Hyper, Actix หรือแม้แต่ thrusterserver ซึ่งเป็นเครื่องยนต์ HTTP ที่ปลูกในบ้าน
ขึ้นอยู่กับเฟรมเวิร์กเช่น KOA และ Express Thruster มุ่งมั่นที่จะพัฒนาด้วย
ในการเรียกใช้ตัวอย่าง cargo run --example <example-name> > ตัวอย่างเช่น cargo run --example hello_world และเปิด http: // localhost: 4321/
ชิ้นส่วนหลักที่ทำให้การทำงานของรหัส Async ใหม่กำลังกำหนดฟังก์ชั่นมิดเดิลแวร์ด้วยแอตทริบิวต์ #[middleware_fn] (ซึ่งทำเครื่องหมายมิดเดิลแวร์เพื่อให้เข้ากันได้กับเวอร์ชันฟิวเจอร์สที่เสถียรที่ Thruster ถูกสร้างขึ้น) จากนั้น m! แมโครในเส้นทางจริง
ตัวอย่างง่ายๆสำหรับการใช้ Async Await คือ:
use std :: boxed :: Box ;
use std :: future :: Future ;
use std :: pin :: Pin ;
use std :: time :: Instant ;
use thruster :: { App , BasicContext as Ctx , Request } ;
use thruster :: { m , middleware_fn , MiddlewareNext , MiddlewareResult , Server , ThrusterServer } ;
# [ middleware_fn ]
async fn profile ( context : Ctx , next : MiddlewareNext < Ctx > ) -> MiddlewareResult < Ctx > {
let start_time = Instant :: now ( ) ;
context = next ( context ) . await ;
let elapsed_time = start_time . elapsed ( ) ;
println ! (
"[{}μs] {} -- {}" ,
elapsed_time . as_micros ( ) ,
context . request . method ( ) ,
context . request . path ( )
) ;
Ok ( context )
}
# [ middleware_fn ]
async fn plaintext ( mut context : Ctx , _next : MiddlewareNext < Ctx > ) -> MiddlewareResult < Ctx > {
let val = "Hello, World!" ;
context . body ( val ) ;
Ok ( context )
}
# [ middleware_fn ]
async fn four_oh_four ( mut context : Ctx , _next : MiddlewareNext < Ctx > ) -> MiddlewareResult < Ctx > {
context . status ( 404 ) ;
context . body ( "Whoops! That route doesn't exist!" ) ;
Ok ( context )
}
# [ tokio :: main ]
fn main ( ) {
println ! ( "Starting server..." ) ;
let mut app = App :: < Request , Ctx , ( ) > :: new_basic ( ) ;
app . get ( "/plaintext" , m ! [ profile , plaintext ] ) ;
app . set404 ( m ! [ four_oh_four ] ) ;
let server = Server :: new ( app ) ;
server . build ( "0.0.0.0" , 4321 ) . await ;
}นี่เป็นตัวอย่างที่ดี
use thruster :: errors :: ThrusterError as Error ;
use thruster :: proc :: { m , middleware_fn } ;
use thruster :: { map_try , App , BasicContext as Ctx , Request } ;
use thruster :: { MiddlewareNext , MiddlewareResult , MiddlewareReturnValue , Server , ThrusterServer } ;
# [ middleware_fn ]
async fn plaintext ( mut context : Ctx , _next : MiddlewareNext < Ctx > ) -> MiddlewareResult < Ctx > {
let val = "Hello, World!" ;
context . body ( val ) ;
Ok ( context )
}
# [ middleware_fn ]
async fn error ( mut context : Ctx , _next : MiddlewareNext < Ctx > ) -> MiddlewareResult < Ctx > {
let res = "Hello, world" . parse :: < u32 > ( )
. map_err ( |_| {
let mut context = Ctx :: default ( ) ;
context . status ( 400 ) ;
ThrusterError {
context ,
message : "Custom error message" . to_string ( ) ,
cause : None ,
}
} ? ;
context . body ( & format ! ( "{}" , non_existent_param ) ) ;
Ok ( context )
}
# [ tokio :: main ]
fn main ( ) {
println ! ( "Starting server..." ) ;
let app = App :: < Request , Ctx , ( ) > :: new_basic ( )
. get ( "/plaintext" , m ! [ plaintext ] )
. get ( "/error" , m ! [ error ] ) ;
let server = Server :: new ( app ) ;
server . build ( "0.0.0.0" , 4321 ) . await ;
} Thruster จัดเตรียมชุดทดสอบที่ง่ายเพื่อทดสอบจุดสิ้นสุดของคุณเพียงแค่รวมโมดูล testing ดังต่อไปนี้:
let mut app = App :: < Request , Ctx , ( ) > :: new_basic ( ) ;
.. .
app . get ( "/plaintext" , m ! [ plaintext ] ) ;
.. .
let result = testing :: get ( app , "/plaintext" ) ;
assert ! ( result . body == "Hello, World!" ) ; มิดเดิลแวร์ทำง่ายสุด ๆ ! เพียงสร้างฟังก์ชั่นและส่งออกในระดับโมดูล ด้านล่างคุณจะเห็นมิดเดิลแวร์ชิ้นหนึ่งที่อนุญาตให้ทำโปรไฟล์คำขอ:
# [ middleware_fn ]
async fn profiling < C : ' static + Context + Send > (
mut context : C ,
next : MiddlewareNext < C > ,
) -> MiddlewareResult < C > {
let start_time = Instant :: now ( ) ;
context = next ( context ) . await ? ;
let elapsed_time = start_time . elapsed ( ) ;
info ! ( "[{}μs] {}" , elapsed_time . as_micros ( ) , context . route ( ) ) ;
Ok ( context )
}คุณอาจพบว่าคุณต้องการอนุญาตให้เก็บข้อมูลที่เฉพาะเจาะจงมากขึ้นในบริบทเช่นบางทีคุณอาจต้องการให้พารามิเตอร์การสืบค้นไฮเดรตลงใน HashMap สำหรับการใช้งานในภายหลังโดย Middlewares อื่น ๆ ในการทำเช่นนี้คุณสามารถสร้างลักษณะเพิ่มเติมสำหรับบริบทที่ Diddlewares downstream ต้องปฏิบัติตาม ตรวจสอบตัวอย่างมิดเดิลแวร์ query_params ที่ให้ไว้สำหรับตัวอย่าง
Thruster มีความสามารถในการจัดหาเลเยอร์การกำหนดเส้นทางที่ด้านบนของเซิร์ฟเวอร์บางประเภทตัวอย่างเช่นในตัวอย่างไฮเปอร์ด้านบน สิ่งนี้สามารถนำไปใช้กับแบ็กเอนด์ใด ๆ ได้ตราบใดที่เซิร์ฟเวอร์ใช้งาน ThrusterServer
use async_trait :: async_trait ;
# [ async_trait ]
pub trait ThrusterServer {
type Context : Context + Send ;
type Response : Send ;
type Request : RequestWithParams + Send ;
fn new ( App < Self :: Request , Self :: Context > ) -> Self ;
async fn build ( self , host : & str , port : u16 ) ;
}จำเป็นต้องเป็น:
ภายในฟังก์ชั่น build การใช้งานเซิร์ฟเวอร์ควร:
let matched = app.resolve_from_method_and_path(<some method>, <some path>); (นี่คือการกำหนดเส้นทางที่แท้จริง)app.resolve(<incoming request>, matched) (จะเรียกใช้มิดเดิลแวร์ที่ถูกล่ามโซ่) fn ip_guard ( head : & RequestHead ) -> bool {
// Check for the cloudflare IP header
let ip = if let Some ( val ) = head . headers ( ) . get ( CF_IP_HEADER ) {
val . to_str ( ) . unwrap_or ( "" ) . to_owned ( )
} else if let Some ( val ) = head . peer_addr {
val . to_string ( )
} else {
return false ;
} ;
"1.2.3.4" . contains ( & ip )
}
# [ actix_web :: post ( "/ping" ) ]
async fn ping ( ) -> Result < HttpResponse , UserPersonalError > {
Ok ( HttpResponse :: Ok ( ) . body ( "pong" ) )
}
.. .
web :: scope ( "/*" )
// This is confusing, but we catch all routes that _aren't_
// ip guarded and return an error.
. guard ( guard :: Not ( ip_guard ) )
. route ( "/*" , web :: to ( HttpResponse :: Forbidden ) ) ,
)
. service ( ping ) ;
.. .นี่คือ Thruster:
# [ middleware_fn ]
async fn ip_guard ( mut context : Ctx , next : MiddlewareNext < Ctx > ) -> MiddlewareResult < Ctx > {
if "1.2.3.4" . contains ( & context . headers ( ) . get ( "Auth-Token" ) . unwrap_or ( "" ) ) {
context = next ( context ) . await ? ;
Ok ( context )
} else {
Err ( Error :: unauthorized_error ( context ) )
}
}
# [ middleware_fn ]
async fn ping ( mut context : Ctx , _next : MiddlewareNext < Ctx > ) -> MiddlewareResult < Ctx > {
context . body ( "pong" ) ;
Ok ( context )
}
.. .
app . get ( "/ping" , m ! [ ip_guard , plaintext ] ) ;
.. .โดยตรงมากขึ้นเป็นสิ่งที่ดี!
ถ้าคุณได้มาไกลขนาดนี้ขอบคุณสำหรับการอ่าน! อย่าลังเลที่จะเอื้อมมือออกไป