-
-
Notifications
You must be signed in to change notification settings - Fork 50
/
cookies.rs
72 lines (67 loc) · 2.86 KB
/
cookies.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//! Using tower_cookies as an Axum extractor right now is the best way to work with cookies from rspc.
//! An official API will likely exist in the future but this works well for now.
use std::{ops::Add, path::PathBuf};
use axum::routing::get;
use rspc::{integrations::httpz::Request, Config};
use time::OffsetDateTime;
use tower_cookies::{Cookie, CookieManagerLayer, Cookies};
use tower_http::cors::{Any, CorsLayer};
pub struct Ctx {
cookies: Cookies,
}
#[tokio::main]
async fn main() {
let router =
rspc::Router::<Ctx>::new()
.config(Config::new().export_ts_bindings(
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../bindings.ts"),
))
.query("getCookie", |t| {
t(|ctx, _: ()| {
ctx.cookies
.get("myDemoCookie")
.map(|c| c.value().to_string())
})
})
.mutation("setCookie", |t| {
t(|ctx, new_value: String| {
let mut cookie = Cookie::new("myDemoCookie", new_value);
cookie.set_expires(Some(OffsetDateTime::now_utc().add(time::Duration::DAY)));
cookie.set_path("/"); // Ensure you have this or it will default to `/rspc` which will cause issues.
ctx.cookies.add(cookie);
})
})
.build()
.arced(); // This function is a shortcut to wrap the router in an `Arc`.
let app = axum::Router::new()
.with_state(())
.route("/", get(|| async { "Hello 'rspc'!" }))
// Attach the rspc router to your axum router. The closure is used to generate the request context for each request.
.nest(
"/rspc",
router
.endpoint(|mut req: Request| {
// TODO: This API is going to be replaced with a httpz cookie manager in the next release to deal with Axum's recent changes.
let cookies = req
.deprecated_extract::<Cookies, ()>()
.expect("The Axum state doesn't match the router. Ensure you added `with_state(T)` where `T` matches the second generic!")
.unwrap();
Ctx { cookies }
})
.axum(),
)
.layer(CookieManagerLayer::new())
// We disable CORS because this is just an example. DON'T DO THIS IN PRODUCTION!
.layer(
CorsLayer::new()
.allow_methods(Any)
.allow_headers(Any)
.allow_origin(Any),
);
let addr = "[::]:4000".parse::<std::net::SocketAddr>().unwrap(); // This listens on IPv6 and IPv4
println!("listening on http://{}/rspc/version", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}