-
Notifications
You must be signed in to change notification settings - Fork 11
Preview
Locks are removed from the context now!
In version 0.4, you may access the request method like this:
let method = ctx.req().await.method.clone();
But now, you can just borrow it.
let method = &ctx.req.method;
All public fields of context can be accessed by field name.
In version 0.4, both of middleware itself and context need to be boxed by Rc/Arc before they are passed tohandle
method of Middleware
(or call
method of Endpoint
).
But now, they can be passed in pure reference.
use roa::{Context, Result, Endpoint};
async fn endpoint(ctx: &mut Context) -> Result {
unimplemented!()
}
let mut ctx = Context::fake();
endpoint.call(&mut ctx).await?;
Now, trait State
is just an alias for 'static + Clone + Send + Sync + Sized
, and the app.state
will be cloned and passed by context when a request inbounds.
use roa::{App, Context, Result};
#[derive(Clone)]
struct State {
id: i32,
}
async fn endpoint(ctx: &mut Context<State>) -> Result {
// As Context implement Deref<Target = State> and DerefMut,
// you can access fields straightly.
assert_eq!(1, ctx.id);
ctx.id = 2
Ok(())
}
// init state with id=1
let app = App::state(State {id: 1}).end(endpoint);
There is an individual storage in each context, you can store or load any data in it.
use roa::{App, Context, Result, Next};
struct Data(i32);
async fn gate(ctx: &mut Context, next: Next<'_>) -> Result {
ctx.store("id", Data(1));
next.await
}
async fn end(ctx: &mut Context) -> Result {
assert_eq!(1, ctx.load::<Data>("id").unwrap().0);
Ok(())
}
let app = App::new().gate(gate).end(end);
Now you can access global executor by context.
use roa::{Context, Result};
async fn endpoint(ctx: &mut Context) -> Result {
let id = ctx.exec.spawn(async {1i32}).await;
let words = ctx.exec.spawn_blocking(|| "Hello, world!").await;
Ok(())
}
Now all errors will be cast to Status(500 INTERNAL SERVER ERROR)
by default, you can straightly throw unexpected errors!
use roa::{Context, Result};
async fn endpoint(ctx: &mut Context) -> Result {
let id: usize = "x".parse()?;
unreachable!()
}
In version 0.4, you may call the next middleware by next().await
. However, as future in rust won't be executed until you poll(await), it's more reasonable if next is a future rather than a function.
Now, you can call the next middleware by next.await
.
use roa::{Context, Result, Next};
async fn gate(ctx: &mut Context, next: Next<'_>') -> Result {
next.await
}
Now roa supports tls, refer to cookbook for more details.
Now roa supports websocket, refer to cookbook for more details.
Now roa supports multipart form, refer to cookbook for more details.
The roa-diesel crate provides integration of diesel, please refer to docs or integration example for more details.
The roa-pg crate provides integration of tokio-postgres, refer to cookbook for more details.
The roa-juniper crate provides integration of juniper. However, you cannot get it from crates.io until juniper v0.14.3 is published.
You can preview this feature in integration-example.
Roa framework use async runtime and TcpStream of async-std by default. You can disable this feature in Cargo.toml.
roa = { version = "0.5.0", default-features = false}
The roa-tokio crate provides tokio-based async runtime and TcpStream.
Refer to cookbook for more details.