Trying to use Session with Graphql using Poem #1149
-
How do I access the session in the query mutation subscription? trying to do authentication with the session, should I be doing it with http headers instead? Any help greatly appriciated! |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 3 replies
-
You can do it like this: #[handler]
fn graphql_subscription(
session: &Session,
schema: Data<&MySchema>, // extract the graphql schema
protocol: GraphQLProtocol,
websocket: WebSocket,
) -> impl IntoResponse {
let schema = schema.0.clone();
let mut data = async_graphql::Data::default();
// extract the username from session and then insert it to data
let username = session.get::<String>("username");
if let Some(username) = username {
data.insert(username);
}
websocket
.protocols(ALL_WEBSOCKET_PROTOCOLS)
.on_upgrade(move |stream| {
GraphQLWebSocket::new(stream, schema, protocol)
.with_data(data) // attach the data to the graphql context
.serve()
})
} let app = Route::new()
.at("/ws", get(graphql_subscription))
.data(schema); // don't forget attach the graphql schema to the incoming http requests |
Beta Was this translation helpful? Give feedback.
-
#[handler]
async fn graphql_endpoint(
session: &Session,
schema: Data<&Schema>,
req: GraphQLRequest,
) -> GraphQLResponse {
let mut req = req.0;
let schema = schema.0.clone();
let cookie = session.get::<String>(JWT_COOKIE);
schema.execute(req.data(cookie)).await.into()
} |
Beta Was this translation helpful? Give feedback.
-
For those struggling with the same issue in Axum, here's my solution. First define your router like this: Router::new()
.route(
"/api/graphql",
post(graphql_handler),
)
.route("/api/graphql/ws",
get(graphql_subscription)) You can use your own async fn graphql_subscription(
State(AppState { graphql_schema, .. }): State<AppState>,
protocol: GraphQLProtocol,
websocket: WebSocketUpgrade,
) -> impl IntoResponse {
let mut data = Data::default();
data.insert(todo!("insert your context here"));
websocket
.protocols(ALL_WEBSOCKET_PROTOCOLS)
.on_upgrade(move |stream| {
GraphQLWebSocket::new(stream, graphql_schema, protocol)
.with_data(data) // attach the data to the graphql context
.serve()
})
} Then in your subscription, you can access your context like this: #[Subscription]
impl RootSubscription {
async fn notifications(
&self,
ctx: &Context<'_>,
) -> impl Stream<Item = YourResponseTypeHere> {
let ctx = ctx.data_opt::<YourContextHereType>().unwrap();
}
} This is useful for e.g. auth and i18n purposes. |
Beta Was this translation helpful? Give feedback.
You can do it like this: