Skip to content

Commit 71ab75a

Browse files
authored
Merge pull request #55 from bvanneerven/master
Add `token-from-header` example for `axum`
2 parents fa8fc5d + 3573b9c commit 71ab75a

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ members = [
3131
"axum/starwars",
3232
"axum/subscription",
3333
"axum/upload",
34+
"axum/token-from-header",
3435

3536
"tide/starwars",
3637
"tide/dataloader",

axum/token-from-header/Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "axum-token-from-header"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
async-graphql = { path = "../../.." }
8+
async-graphql-axum = { path = "../../../integrations/axum" }
9+
tokio = { version = "1.8", features = ["macros", "rt-multi-thread"] }
10+
token = { path = "../../models/token" }
11+
hyper = "0.14"
12+
axum = { version = "0.5.1", features = ["ws", "headers"] }

axum/token-from-header/src/main.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use async_graphql::{
2+
http::{playground_source, GraphQLPlaygroundConfig, ALL_WEBSOCKET_PROTOCOLS},
3+
Data, EmptyMutation, Schema,
4+
};
5+
use async_graphql_axum::{GraphQLProtocol, GraphQLRequest, GraphQLResponse, GraphQLWebSocket};
6+
use axum::{
7+
extract::{ws::WebSocketUpgrade, Extension},
8+
http::header::HeaderMap,
9+
response::{Html, IntoResponse, Response},
10+
routing::get,
11+
Router, Server,
12+
};
13+
use token::{on_connection_init, QueryRoot, SubscriptionRoot, Token, TokenSchema};
14+
15+
async fn graphql_playground() -> impl IntoResponse {
16+
Html(playground_source(
17+
GraphQLPlaygroundConfig::new("/").subscription_endpoint("/ws"),
18+
))
19+
}
20+
21+
fn get_token_from_headers(headers: &HeaderMap) -> Option<Token> {
22+
headers
23+
.get("Token")
24+
.and_then(|value| value.to_str().map(|s| Token(s.to_string())).ok())
25+
}
26+
27+
async fn graphql_handler(
28+
req: GraphQLRequest,
29+
Extension(schema): Extension<TokenSchema>,
30+
headers: HeaderMap,
31+
) -> GraphQLResponse {
32+
let mut req = req.into_inner();
33+
if let Some(token) = get_token_from_headers(&headers) {
34+
req = req.data(token);
35+
}
36+
schema.execute(req).await.into()
37+
}
38+
39+
async fn graphql_ws_handler(
40+
Extension(schema): Extension<TokenSchema>,
41+
protocol: GraphQLProtocol,
42+
websocket: WebSocketUpgrade,
43+
headers: HeaderMap,
44+
) -> Response {
45+
let mut data = Data::default();
46+
if let Some(token) = get_token_from_headers(&headers) {
47+
data.insert(token);
48+
}
49+
50+
websocket
51+
.protocols(ALL_WEBSOCKET_PROTOCOLS)
52+
.on_upgrade(move |stream| {
53+
GraphQLWebSocket::new(stream, schema.clone(), protocol)
54+
.with_data(data)
55+
.on_connection_init(on_connection_init)
56+
.serve()
57+
})
58+
}
59+
60+
#[tokio::main]
61+
async fn main() {
62+
let schema = Schema::new(QueryRoot, EmptyMutation, SubscriptionRoot);
63+
64+
let app = Router::new()
65+
.route("/", get(graphql_playground).post(graphql_handler))
66+
.route("/ws", get(graphql_ws_handler))
67+
.layer(Extension(schema));
68+
69+
println!("Playground: http://localhost:8000");
70+
71+
Server::bind(&"0.0.0.0:8000".parse().unwrap())
72+
.serve(app.into_make_service())
73+
.await
74+
.unwrap();
75+
}

0 commit comments

Comments
 (0)