Mulailah dengan contoh dan walkthrough di situs web kami!
Tidak punya waktu untuk membaca dokumen? Memeriksa
✅ berjalan di stabil ✅ berjalan cepat ✅ tidak menggunakan yang tidak aman
Dokumentasi
Thruster adalah kerangka kerja web yang bertujuan bagi pengembang untuk menjadi produktif dan konsisten di seluruh proyek dan tim. Tujuannya adalah:
Thruster juga
unsafeThruster dapat dijalankan dengan backend server yang berbeda dan mewakili lapisan yang dikemas dengan baik di atasnya. Ini berarti bahwa ia dapat mengimbangi perubahan terbaru dan terhebat dari orang-orang seperti Hyper, Actix, atau bahkan Thrusterserver, mesin HTTP yang ditanam di rumah.
Berdasarkan kerangka kerja seperti KOA, dan Express, Thruster bertujuan untuk menjadi senang untuk dikembangkan.
Untuk menjalankan contoh cargo run --example <example-name> . Misalnya, cargo run --example hello_world dan buka http: // localhost: 4321/
Bagian -bagian inti yang membuat Code Work Await baru adalah menunjuk fungsi middleware dengan atribut #[middleware_fn] (yang menandai middleware sehingga kompatibel dengan versi berjangka stabil yang dorong dorong,) dan kemudian m! makro di rute yang sebenarnya.
Contoh sederhana untuk menggunakan async menunggu adalah:
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 ;
}Inilah contoh yang bagus
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 menyediakan suite tes mudah untuk menguji titik akhir Anda, cukup sertakan modul testing seperti di bawah ini:
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 sangat mudah dibuat! Cukup buat fungsi dan ekspor di level modul. Di bawah ini, Anda akan melihat sepotong middleware yang memungkinkan profil permintaan:
# [ 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 )
}Anda mungkin menemukan bahwa Anda ingin mengizinkan data yang lebih spesifik yang disimpan pada konteksnya, misalnya, mungkin Anda ingin dapat menghidrasi parameter kueri ke dalam hashmap untuk digunakan nanti oleh tuduhan tengah lainnya. Untuk melakukan ini, Anda dapat membuat ciri tambahan untuk konteks yang harus dipatuhi oleh Middlewares di hilir. Lihatlah middleware Query_params yang disediakan sebagai contoh.
Thruster mampu menyediakan lapisan perutean di atas server, misalnya, di cuplikan hiper di atas. Ini dapat diterapkan secara luas untuk backend apa pun, selama server mengimplementasikan 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 ) ;
}Perlu ada:
Dalam fungsi build , implementasi server harus:
let matched = app.resolve_from_method_and_path(<some method>, <some path>); (Ini menyediakan perutean yang sebenarnya.)app.resolve(<incoming request>, matched) (ini menjalankan middleware rantai.) 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 ) ;
.. .Ini 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 ] ) ;
.. .Sedikit lebih langsung itu bagus!
Jika Anda sampai sejauh ini, terima kasih sudah membaca! Selalu merasa bebas untuk menjangkau.